Регулировка десятичной точности, .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?
Решение
Сохранение следующих нулей, подобных этому, было введено в .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, если применяется соответствующая строка формата.
Как насчетMath.round (Decimal D, Int Decimals)?
Я обнаружил, что могу «подделать» шкал, умножив или делясь на причудливый 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 м.