Давайте попробуем понять, в чем разница между типами переменных 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