Вопрос

Эти строки в C#

decimal a = 2m;
decimal b = 2.0m;
decimal c = 2.00000000m;
decimal d = 2.000000000000000000000000000m;

Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);

Генерирует этот вывод:

2
2.0
2.00000000
2.000000000000000000000000000

Поэтому я вижу, что создание десятичной переменной из литерала позволяет мне контролировать точность.

  • Могу ли я настроить точность десятичных переменных без использования литералов?
  • Как я могу создать B из A? Как я могу создать B из C?
Это было полезно?

Решение

Сохранение следующих нулей, подобных этому, было введено в .NET 1.1 для более строгого соответствия спецификации ECMA CLI.

Есть некоторая информация об этом на MSDN, например, здесь.

Вы можете настроить точность следующим образом:

  • Математика.

  • Умножьте на 1.000 ... (с количеством десятичных десятичных видов), чтобы повысить точность - например, умножьте на 1,0 м, чтобы получить B из a.

Другие советы

Вы просто видите разные представления одних и тех же данных. Точность decimal будет масштабирован, чтобы быть таким же большим, как это должно быть (в пределах разумного).

Из System.Decimal:

Десятичное число-это значение с плавающей запятой, которое состоит из знака, числового значения, где каждая цифра в значении колеблется от 0 до 9, и и Коэффициент масштабирования, который указывает на положение плавающей десятичной точки, которая разделяет интегральные и дробные части числового значения.

Бинарное представление десятичного значения состоит из 1-битного знака, 96-битного целого числа и коэффициента масштабирования, используемого для разделения 96-битного целого числа, и указать, какая его часть является десятичной фракцией. Коэффициент масштабирования неявно является числом 10, поднятым до показателя в диапазоне от 0 до 28. Следовательно, бинарное представление десятичного значения имеет форму (-296 до 296) / 10(От 0 до 28)), где -296-1 равен MinValue и 296-1 равен MaxValue.

Коэффициент масштабирования также сохраняет любые следы за следами десятичного числа. Следующие нули не влияют на значение десятичного числа в арифметических или сравнительных операциях. Тем не менее, следы за следами могут быть обнаружены методом ToString, если применяется соответствующая строка формата.

Я обнаружил, что могу «подделать» шкал, умножив или делясь на причудливый 1.

decimal a = 2m;
decimal c = 2.00000000m;
decimal PreciseOne = 1.000000000000000000000000000000m;
  //add maximum trailing zeros to a
decimal x = a * PreciseOne;
  //remove all trailing zeros from c
decimal y = c / PreciseOne;

Я могу изготовить достаточно точный 1, чтобы изменить факторы масштаба по известным размерам.

decimal scaleFactorBase = 1.0m;
decimal scaleFactor = 1m;
int scaleFactorSize = 3;

for (int i = 0; i < scaleFactorSize; i++)
{
  scaleFactor *= scaleFactorBase;
}

decimal z = a * scaleFactor;

Заманчиво путать decimal в SQL Server с decimal в .net; Они совершенно разные.

SQL Server decimal это число с фиксированной точкой, точность и масштаба, точность и масштаб, при определении столбца или переменной.

ЧИСТАЯ decimal это номер с плавающей точкой, как float а также double (Разница в том, что decimal точно сохраняет десятичные цифры, тогда как float а также double точно сохранить бинарные цифры). Попытка контролировать точность .NET decimal бессмысленно, поскольку все расчеты дадут одинаковые результаты независимо от наличия или отсутствия нулей на прокладки.

Вопрос в том, действительно ли вам нужна точность хранится В десятичном значении, а не просто демонстрировать десятичное значение с необходимой точностью. Большинство приложений знают внутренне, насколько точнее они хотят быть, и отображаются до такого уровня точности. Например, даже если пользователь входит в счет на 100 в пакете учетных записей, он все равно выводит 100,00, используя что -то вроде val.tostring («n2»).

Как я могу создать B из A? Как я могу создать B из C?

C к B возможен.

Console.WriteLine(Math.Round(2.00000000m, 1)) 

производит 2.0

А до б сложна, так как концепция введения точности - немного чужды для математики.

Я думаю, что ужасный хак может быть туда и обратно.

decimal b = Decimal.Parse(a.ToString("#.0"));
Console.WriteLine(b);

производит 2.0

Это удалит все зацепленные нули из десятичного значения, а затем вы можете просто использовать ToString().

public static class DecimalExtensions
{
    public static Decimal Normalize(this Decimal value)
    {
        return value / 1.000000000000000000000000000000000m;
    }
}

Или, в качестве альтернативы, если вам нужно точное количество норсов, скажем, 5, сначала нормализовать (), а затем умножьте на 1,00000 м.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top