Регулировка десятичной точности, .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

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

Can I adjust the precision of decimal variables without using literals? How can I create b from a? How can I create b from c?

Ответы на вопрос(7)

нужна ли вам точностьstored в десятичном виде, а не просто отображение десятичного знака с необходимой точностью. Большинство приложений знают, насколько они точны, и отображают их с таким уровнем точности. Например, даже если пользователь вводит счет-фактуру на 100 в пакете учетных записей, он все равно печатает как 100,00, используя что-то вроде val.ToString (& quot; n2 & quot;).

How can I create b from a? How can I create b from c?

с б возможно.

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, сначала Normalize (), а затем умножьте на 1.00000m.

 26 авг. 2013 г., 15:43
Нет необходимостиthat много нулей, можно сделать с 28 нулями после1, Смотрите комментарии кother answer.

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

ОтSystem.Decimal:

A decimal number is a floating-point value that consists of a sign, a numeric value where each digit in the value ranges from 0 to 9, and a scaling factor that indicates the position of a floating decimal point that separates the integral and fractional parts of the numeric value.

The binary representation of a Decimal value consists of a 1-bit sign, a 96-bit integer number, and a scaling factor used to divide the 96-bit integer and specify what portion of it is a decimal fraction. The scaling factor is implicitly the number 10, raised to an exponent ranging from 0 to 28. Therefore, the binary representation of a Decimal value is of the form, ((-296 to 296) / 10(0 to 28)), where -296-1 is equal to MinValue, and 296-1 is equal to MaxValue.

The scaling factor also preserves any trailing zeroes in a Decimal number. Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations. However, trailing zeroes can be revealed by the ToString method if an appropriate format string is applied.

 15 июл. 2009 г., 20:43
@ Дэвид - звучит хорошо.
 Amy B15 июл. 2009 г., 19:33
Хорошая информация о коэффициенте масштабирования ... теперь, как я могу его настроить?
 15 июл. 2009 г., 19:57
Коэффициент масштабирования не контролируется напрямую, поскольку он регулируется в зависимости от размера показателя степени. Это в основном то, как работает плавающая точка (и откуда взялся термин «плавающий»). Поскольку число битов в значимом значении является постоянным, размер числа определяет масштаб значащих битов.
 Amy B15 июл. 2009 г., 20:42
Есть причина - однако, я чувствую, что причина не добавляет ясности этому вопросу. Я, вероятно, задам отдельный вопрос о причине.
 15 июл. 2009 г., 19:58
Он автоматически настраивается в соответствии с потребностями данных, которые он содержит. Есть ли конкретная причина, по которой вам нужно масштабировать его вручную?

что могу «подделать» со шкалой путем умножения или деления на фантазии 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;
 15 июл. 2009 г., 22:42
Интересно, но в то же время озадачивает. В чем разница между 2,0м и 2,00000000м? В не вычислительной среде я бы взял это, чтобы означать, что последнее число было гарантировано с такой точностью, тогда как первое было гарантировано только до первой десятичной запятой. Однако умножение должно означать, что результат является точным с точностью до одного знака после запятой.
Решение Вопроса

decimal в SQL Server сdecimal в .NET; они совсем разные.

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

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

 27 сент. 2011 г., 02:00
что интересно, установка граней на десятичную дробь в EF создает правильнуюSQL decimal который быстро терпит неудачу, когдаc# decimal передал это ... в моем случае я использовал Precision: 2, Scale: (none), и я не могу назначить800 к нему из-за значения вне диапазона
Решение Вопроса

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

На MSDN есть некоторая информация, например,Вот.

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

Math.Round (or Ceiling, Floor etc) to decrease precision (b from c)

Multiply by 1.000... (with the number of decimals you want) to increase precision - e.g. multiply by 1.0M to get b from a.

 26 авг. 2013 г., 15:41
Такжеdivide от1.000... чтобы уменьшить точность.
 03 нояб. 2016 г., 11:38
Для значений .00 вы должны сначала умножить на 1.00m: decimal.Round (значение * 1.00m, 2)

Ваш ответ на вопрос