Подтвердить что ты не робот

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

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

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 из? Как я могу создать b из c?
4b9b3361

Ответ 1

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

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

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

  • Math.Round(или потолок, пол и т.д.) для уменьшения точности (b от c)

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

Ответ 2

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

Из System.Decimal:

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

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

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

Ответ 4

Я обнаружил, что могу "подделать" шкалу умножением или делением на фантазию 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;

Ответ 5

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

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

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

Ответ 6

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

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

c к b.

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

производит 2,0

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

Я думаю, что ужасный взлом может быть в оба конца.

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

производит 2,0

Ответ 7

Это приведет к удалению всех конечных нулей из десятичной дроби, а затем вы можете просто использовать ToString().

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

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