Существуют ли разные десятичные значения для нуля? - PullRequest
3 голосов
/ 02 апреля 2019

Я работаю в коде C #, который назначает десятичные значения следующими способами.Это одинаковые значения или разница?

decimal a = 0;
decimal b = 0m;
decimal c = 0.00m;

Ответы [ 2 ]

4 голосов
/ 02 апреля 2019

Просто добавив немного более практичной информации к другим хорошим ответам

Десятичные числа имеют много внутренних представлений 0, однако все они будут равны нулю , когда сравнивается

Десятичная структура

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

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

Пример изменения коэффициента масштабирования

string GetBits(decimal d)
{
   var bits = decimal.GetBits(d);
   return $"{d==0} {d,31}  {bits[3],10:X8}{bits[2],10:X8}{bits[1],10:X8}{bits[0],10:X8}";
}

Console.WriteLine(GetBits(0));
Console.WriteLine(GetBits(0.0m));
Console.WriteLine(GetBits(0.000m));
// Manually set the Scaling Factor and Sign
Console.WriteLine(GetBits(new decimal(0,0,0,true,10)));

выход

Equals 0                    ToString       Other        Hi       Mid        Lo
------------------------------------------------------------------------------
True                               0    00000000  00000000  00000000  00000000
True                             0.0    00010000  00000000  00000000  00000000
True                           0.000    00030000  00000000  00000000  00000000
True                    0.0000000000    800A0000  00000000  00000000  00000000
3 голосов
/ 02 апреля 2019

Разница действительно есть, но она, скорее всего, не будет проблемой, если вы об этом знаете.

Во-первых, как указал Бен Коттрелл в своем ответе, все эти значения будут равны,Фактически decimal a = 0; приведёт значение 0 к 0m, что делает его фактически идентичным ba, и b будут проверяться как равные 0.00m или любому другому изменению числа десятичных знаков.

Разница заключается в том, когда вы смотрите на внутренние органы.Это действительно актуально только тогда, когда вы сериализуете десятичные числа как байтовые массивы или используете массив, возвращаемый decimal.GetBits().В этом случае 0M равен 16 x 0 байтов, а 0.00M имеет масштаб 2, поэтому один из байтов в двоичном представлении (байт 14) не равен нулю.

Также строковая формаони будут различаться, поэтому сравнение строк не удастся:

decimal a = 0M;
decimal b = 0.00M;
if (a.ToString() != b.ToString())
    Console.WriteLine($"'{a}' != '{b}'");

Таким образом, пока они равны, они все равно различны.

...