Давайте попробуем понять, в чем разница между типами переменных decimal, float и double в .NET, и когда их следует использовать в правильном случае, и какова точность каждого из них.
float
и double
— это бинарные точки с плавающей запятой. Другими словами, они представляют число следующим образом:
10001.10010110011
Двоичное число и расположение двоичной точки закодированы внутри значения.
decimal
– это тип десятичной точки с плавающей запятой. Другими словами, они представляют число следующим образом:
12345.65789
Опять же, число и расположение десятичной точки закодированы внутри значения — это то, что делает decimal
по-прежнему типом с плавающей запятой, а не типом с фиксированной запятой.
Важно отметить, что люди привыкли представлять нецелые числа в десятичной форме и ожидают точных результатов в десятичных представлениях; не все десятичные числа точно представляются в двоичном формате с плавающей запятой — например, 0,1 — поэтому, если вы используете двоичное значение с плавающей запятой, вы фактически получите приближение к 0,1. Вы по-прежнему будете получать приблизительные значения при использовании десятичной точки с плавающей запятой — например, результат деления 1 на 3 не может быть точно представлен.
Что использовать, когда:
- Для значений, которые являются «естественно точными десятичными знаками», хорошо использовать
decimal
. Обычно это подходит для любых понятий, придуманных людьми: самый очевидный пример — финансовые ценности, но есть и другие. Возьмем, к примеру, баллы, присуждаемые ныряльщикам или фигуристам. - Для значений, которые являются в большей степени артефактами природы, которые в любом случае не могут быть измерены точно, более подходящими являются
float
/double
. Например, научные данные обычно представляются в такой форме. Здесь исходные значения не будут «десятично точными» для начала, поэтому для ожидаемых результатов не важно поддерживать «десятичную точность». С плавающей двоичной точкой работать намного быстрее, чем с десятичной.
И тем более точность является основным отличием.
Плавающая — 7 цифр (32 бита)
Двойной - 15–16 цифр (64 разряда)
Десятичный -28–29 значащих цифр (128 бит)
Десятичные числа имеют гораздо более высокую точность и обычно используются в финансовых приложениях, требующих высокой степени точности. Десятичные числа намного медленнее (до 20 раз в некоторых тестах), чем двойные/плавающие.
Десятичные числа и числа с плавающей запятой/двойники нельзя сравнивать без приведения, в то время как числа с плавающей запятой и двойные числа могут. Десятичные числа также допускают кодировку или нули в конце.
float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);
Результат :
float: 0.3333333
double: 0.333333333333333
decimal: 0.3333333333333333333333333333