Настройка десятичной точности, .net



эти строки в 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?

502   7  

7 ответов:

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

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

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

  • математика.Круглый (или потолок, пол и т. д.) Для уменьшения точности (b от c)

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

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

С System.Decimal:

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

двоичное представление десятичного числа значение состоит из 1-битного знака, a 96-битное целое число и масштабирование коэффициент, используемый для деления 96-бит целое число и укажите, какая его часть является десятичной дробью. Масштабирование фактор неявно число 10, возведенное в степень от 0 до 28. Таким образом, двоичный представление десятичного значения форма, ((-296 в 296) / 10(0 to 28)), где -296-1 равен MinValue, и 296-1 равен Максвелл.

коэффициент масштабирования также сохраняет любые конечные нули в десятичном числе. Конечные нули не влияют на значение десятичного числа в арифметические операции или операции сравнения. Однако конечные нули могут быть раскрывается методом 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; они совершенно разные.

A SQL Server decimal - Это число с фиксированной точкой, точность и масштаб которого фиксируются при определении столбца или переменной.

A .NET decimal - Это число с плавающей точкой типа float и double (разница в том, что decimal точно сохраняет десятичные цифры, тогда как float и double точно сохранить двоичные цифры). Попытка контролировать точность .NET decimal бессмысленно, так как все вычисления будут давать одинаковые результаты независимо от наличия или отсутствия нулей заполнения.

вопрос в том-Вам действительно нужна точность хранящиеся в десятичной системе счисления, а не просто отображение десятичной системы счисления с требуемой точностью. Большинство приложений знают внутренне, насколько точными они хотят быть, и отображают этот уровень точности. Например, даже если пользователь вводит счет на 100 в пакете счетов, он все равно печатается как 100.00, используя что-то вроде val.ToString ("n2").

Как я могу создать b из a? Как я могу создать b из с?

c к b возможно.

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

производит 2.0

от a до b сложно, поскольку концепция введения точности немного чужда математике.

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

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 м.

Comments

    Ничего не найдено.