Разница между десятичной, плавающей и двойной в .NET?

В чем разница decimal, floatи doubleв .NET?

Когда кто-нибудь будет использовать один из них?

6.03.2009 11:31:23
интересная статья zetcode.com/lang/csharp/datatypes
GibboK 1.03.2014 14:20:15
Pacerier 17.04.2017 19:32:48
18 ОТВЕТОВ
РЕШЕНИЕ

floatи doubleявляются типами с плавающей двоичной точкой . Другими словами, они представляют число как это:

10001.10010110011

Двоичное число и местоположение двоичной точки кодируются в пределах значения.

decimalявляется плавающей десятичной точки типа . Другими словами, они представляют число как это:

12345.65789

Опять же, число и местоположение десятичной точки оба закодированы в пределах значения - это то, что делает decimalтип с плавающей запятой все еще вместо типа с фиксированной запятой.

Важно отметить, что люди привыкли представлять нецелые числа в десятичной форме и ожидать точных результатов в десятичных представлениях; не все десятичные числа точно представимы в двоичной переменной с плавающей запятой - например, 0,1 - поэтому, если вы используете двоичное значение с плавающей запятой, вы фактически получите приближение к 0,1. При использовании плавающей десятичной точки вы все равно получите приближения - например, результат деления 1 на 3 не может быть точно представлен.

Что касается того, что использовать, когда:

  • Для значений, которые являются "естественно точными десятичными числами", это хорошо использовать decimal. Это обычно подходит для любых концепций, изобретенных людьми: наиболее очевидным примером являются финансовые ценности, но есть и другие. Рассмотрим, например, оценку, которую дают дайверам или фигуристам.

  • Для значений, которые являются более артефактами природы, которые в любом случае не могут быть точно измерены , float/ doubleявляются более подходящими. Например, научные данные обычно представляются в такой форме. Здесь исходные значения не будут «десятично точными» для начала, поэтому для ожидаемых результатов не важно поддерживать «десятичную точность». Типы с плавающей двоичной точкой работают намного быстрее, чем десятичные.

2251
26.01.2018 16:42:21
float/ doubleобычно не представляют числа как 101.101110, обычно это представляется как что-то вроде 1101010 * 2^(01010010)- экспонента
Mingwei Samuel 13.08.2014 21:50:33
@Hazzard: Вот что означает часть ответа «и расположение двоичной точки».
Jon Skeet 13.08.2014 21:57:58
Я удивлен, что это еще не было сказано, floatэто псевдоним C # и не тип .Net. это System.Single.. singleи doubleс плавающей точкой двоичные типы.
Brett Caswell 3.02.2015 15:48:58
@BKSpurgeon: Ну, точно так же, как вы можете сказать, что все является двоичным типом, и в этот момент оно становится довольно бесполезным определением. Десятичный тип - это десятичный тип в том смысле, что это число, представленное в виде целого числа и шкалы, такой, что в результате получается значение и * 10 ^ масштаб, тогда как числа с плавающей запятой и двойное имеют значение и * 2 ^ масштаб. Вы берете число, записанное в десятичной дроби, и перемещаете десятичную точку достаточно далеко вправо, чтобы получить целое число для вычисления значения и масштаба. Для float / double вы должны начать с числа, записанного в двоичном формате.
Jon Skeet 26.11.2015 07:20:16
Еще одно отличие: поплавок 32-битный; двойной 64-битный; и десятичное 128-битное.
David 29.08.2016 15:08:54

Точность - это главное отличие.

Float - 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
1069
16.10.2018 14:49:07
@Thecrocodilehunter: извините, но нет. Десятичное число может представлять все числа, которые могут быть представлены в десятичной записи, но не 1/3, например. 1.0m / 3.0m оценивается как 0.33333333 ... с большим, но конечным числом 3s в конце. Умножение на 3 не даст точного 1,0.
Erik P. 29.11.2011 21:14:43
@Thecrocodilehunter: я думаю, что вы путаете точность и точность. Это разные вещи в этом контексте. Точность - это количество цифр, доступных для представления числа. Чем больше точность, тем меньше нужно округлять. Ни один тип данных не имеет бесконечной точности.
Igby Largeman 6.01.2012 17:42:04
@Thecrocodilehunter: Вы предполагаете, что измеряемое значение точно 0.1 - это редко имеет место в реальном мире! Любой конечный формат хранения будет сопоставлять бесконечное количество возможных значений с конечным числом битовых комбинаций. Например, floatбудет сопоставлять 0.1и 0.1 + 1e-8, пока decimalбудет сопоставлять 0.1и 0.1 + 1e-29. Конечно, в пределах данного диапазона определенные значения могут быть представлены в любом формате с нулевой потерей точности (например, floatмогут хранить любое целое число до 1.6e7 с нулевой потерей точности) - но это все еще не бесконечная точность.
Daniel Pryden 10.01.2012 01:49:31
@Thecrocodilehunter: Вы пропустили мою точку зрения. 0.1это не особая ценность ! Единственное, что делает 0.1«лучше», 0.10000001это то, что люди любят основание 10. И даже со floatзначением, если вы инициализируете два значения 0.1одним и тем же способом, они оба будут иметь одинаковое значение . Просто это значение не будет точно 0.1 - это будет самое близкое значение, 0.1которое может быть точно представлено какfloat . Конечно, с двоичными числами, (1.0 / 10) * 10 != 1.0но с десятичными числами (1.0 / 3) * 3 != 1.0тоже. Ни не вполне точным.
Daniel Pryden 10.01.2012 18:27:53
@Thecrocodilehunter: Вы все еще не понимаете. Я не знаю , как сказать , что это уже не ясно: В C, если вы double a = 0.1; double b = 0.1;тогда a == b будете верно . Это просто , что aи bбудет и не совсем равны 0.1. В C #, если вы это сделаете, decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;то a == bтакже будет верно. Но в этом случае, ни в , aни bбудет точно равно 1/3- они оба равны 0.3333.... В обоих случаях некоторая точность теряется из-за представления. Вы упорно говорят , что decimalимеет «бесконечную» точность, которая является ложным .
Daniel Pryden 10.01.2012 19:29:12
  1. Double и float могут быть разделены на целое число ноль без исключения как во время компиляции, так и во время выполнения.
  2. Десятичная дробь не может быть разделена на целое число ноль. Компиляция всегда будет неудачной, если вы это сделаете.
28
29.07.2010 07:21:10
Они уверены, что могут! У них также есть пара «магических» значений, таких как Infinity, Negative Infinity и NaN (не число), которые делают его очень полезным для обнаружения вертикальных линий при вычислении уклонов ... Далее, если вам нужно выбрать между вызовами float .TryParse, double.TryParse и decimal.TryParse (например, для определения, является ли строка числом), я рекомендую использовать double или float, поскольку они будут правильно анализировать "Infinity", "-Infinity" и "NaN" тогда как десятичная дробь не будет.
BrainSlugs83 23.06.2011 19:29:42
Компиляция завершится неудачей только в том случае, если вы попытаетесь разделить литерал decimalна ноль (CS0020), и то же самое верно для целочисленных литералов. Однако, если десятичное значение времени выполнения делится на ноль, вы получите исключение, а не ошибку компиляции.
Drew Noakes 18.11.2016 00:24:11
@ BrainSlugs83 Однако, вы можете не захотеть анализировать «Бесконечность» или «NaN» в зависимости от контекста. Похоже, хороший эксплойт для пользовательского ввода, если разработчик не достаточно строг.
Winter 17.05.2017 01:00:00

Десятичная структура строго ориентирована на финансовые расчеты, требующие точности, которые относительно нетерпимы к округлению. Однако десятичные дроби не подходят для научных приложений по нескольким причинам:

  • Определенная потеря точности допустима во многих научных расчетах из-за практических ограничений физической проблемы или измеряемого артефакта. Потеря точности не приемлема в финансах.
  • Десятичное число намного (намного) медленнее, чем число с плавающей запятой, и двойное для большинства операций, главным образом потому, что операции с плавающей запятой выполняются в двоичном формате, тогда как десятичное число выполняется в базе 10 (т. Е. Числа с плавающей запятой и двойные числа обрабатываются аппаратным обеспечением FPU, таким как MMX / SSE). тогда как десятичные дроби рассчитываются в программном обеспечении).
  • Десятичное число имеет недопустимо меньший диапазон значений, чем double, несмотря на то, что оно поддерживает больше цифр точности. Таким образом, десятичное не может быть использовано для представления многих научных ценностей.
83
13.04.2011 13:55:01
Если вы делаете финансовые расчеты, вам абсолютно необходимо свернуть свои собственные типы данных или найти хорошую библиотеку, которая точно соответствует вашим потребностям. Точность в финансовых условиях определяется (человеческими) органами по стандартизации, и у них есть очень конкретные локализованные (как по времени, так и по географии) правила о том, как проводить расчеты. Такие вещи, как правильное округление, не фиксируются в простых числовых типах данных в .Net. Способность делать вычисления - только очень маленькая часть загадки.
James Moore 6.04.2016 16:59:08

float 7 цифр точности

double имеет около 15 цифр точности

decimal имеет около 28 цифр точности

Если вам нужна лучшая точность, используйте double вместо float. В современных процессорах оба типа данных имеют практически одинаковую производительность. Единственное преимущество использования поплавка - они занимают меньше места. Практически имеет значение, только если у вас их много.

Я нашел это интересно. Что каждый ученый должен знать об арифметике с плавающей точкой

47
15.07.2014 21:42:14
@RogerLipscombe: Я бы посчитал doubleправильным в приложениях учета в тех случаях (и в основном только в тех случаях), где не было доступно ни одного целочисленного типа больше 32 бит, и doubleон использовался так, как если бы это был 53-битный целочисленный тип (например, для хранения). целое количество копеек или целых сотых процента). В наши дни такие вещи не очень полезны, но многие языки получили возможность использовать значения с плавающей запятой двойной точности задолго до того, как они получили 64-битную (или в некоторых случаях даже 32-битную) целочисленную математику.
supercat 29.05.2014 17:57:34
Ваш ответ подразумевает, что точность - единственное различие между этими типами данных. Учитывая, что двоичная арифметика с плавающей запятой обычно реализуется в аппаратном FPU , производительность является существенной разницей. Это может быть несущественным для некоторых приложений, но критичным для других.
saille 15.01.2015 03:16:10
@supercat double никогда не подходит для бухгалтерских приложений. Потому что Double может только аппроксимировать десятичные значения (даже в пределах своей точности). Это связано с тем, что double хранит значения в формате base-2 (двоичный).
BrainSlugs83 14.03.2015 22:50:17
@ BrainSlugs83: Использование типов с плавающей точкой для хранения значений не целых чисел было бы неправильным, но исторически очень часто языки имели типы с плавающей точкой, которые могли точно представлять большие значения целых чисел, чем их целочисленные типы. , Возможно, самым ярким примером был Turbo-87, чьи единственные целочисленные типы были ограничены от -32768 до +32767, но чей RealIIRC мог представлять значения до 1,8E + 19 с точностью до единицы. Я думаю, что было бы гораздо разумнее использовать бухгалтерское приложение для Realпредставления целого числа копеек, чем ...
supercat 15.03.2015 19:45:28
... чтобы попытаться выполнить математику с множественной точностью, используя набор 16-битных значений. Для большинства других языков разница не была такой уж экстремальной, но в течение долгого времени было очень распространено, чтобы языки не имели целочисленного типа, выходящего за пределы 4E9, но имели doubleтип с единичной точностью до 9E15. Если нужно хранить целые числа, которые больше, чем самый большой из доступных целочисленных типов, использование, doubleкак правило, проще и эффективнее, чем попытки выдумать математику с высокой точностью, особенно если учесть, что у процессоров есть инструкции для выполнения 16x16-> 32 или. ..
supercat 15.03.2015 19:47:02

Это была интересная тема для меня, так как сегодня у нас только что была маленькая неприятная ошибка, связанная decimalс меньшей точностью, чем у float.

В нашем коде C # мы читаем числовые значения из электронной таблицы Excel, преобразуем их в a decimal, а затем отправляем decimalобратно в службу для сохранения в базе данных SQL Server .

Microsoft.Office.Interop.Excel.Range cell = 
object cellValue = cell.Value2;
if (cellValue != null)
{
    decimal value = 0;
    Decimal.TryParse(cellValue.ToString(), out value);
}

Теперь, почти для всех наших значений Excel, это работало прекрасно. Но для некоторых очень маленьких значений Excel использование полностью decimal.TryParseпотеряно. Одним из таких примеров является

  • cellValue = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), выходное значение); // вернул бы 0

Как ни странно, решением было преобразовать значения Excel в doubleпервое, а затем в decimal:

Microsoft.Office.Interop.Excel.Range cell = 
object cellValue = cell.Value2;
if (cellValue != null)
{
    double valueDouble = 0;
    double.TryParse(cellValue.ToString(), out valueDouble);
    decimal value = (decimal) valueDouble;
    
}

Несмотря на то, что doubleимеет меньшую точность, чем a decimal, это фактически гарантировало, что небольшие числа все равно будут распознаваться. По какой-то причине double.TryParseудалось на самом деле извлечь такие небольшие числа, тогда как decimal.TryParseустановил бы их на ноль.

Странный. Очень странно.

13
19.02.2018 10:45:39
Из любопытства, каково было необработанное значение cellValue.ToString ()? Кажется, что работает Decimal.TryParse ("0.00006317592", out val) ...
micahtan 27.08.2012 23:57:49
-1 Не поймите меня неправильно, если это правда, это очень интересно, но это отдельный вопрос, это, конечно, не ответ на этот вопрос.
weston 22.05.2013 14:19:05
Возможно, потому что ячейка Excel возвращала double, а значение ToString () было «6.31759E-05», поэтому decimal.Parse () не понравилась запись. Бьюсь об заклад, если бы вы проверили возвращаемое значение Decimal.TryParse (), это было бы ложным.
SergioL 15.10.2014 20:44:52
Ответы @weston часто дополняют другие ответы, заполняя нюансы, которые они пропустили. Этот ответ подчеркивает разницу с точки зрения синтаксического анализа. Это очень большой ответ на вопрос!
Robino 20.05.2015 15:52:39
Э-э ... decimal.Parse("0.00006317592")работает - у тебя что-то еще происходит. - Возможно, научная запись?
BrainSlugs83 16.09.2017 01:15:16

Целые числа, как уже упоминалось, являются целыми числами. Они не могут хранить в себе что-то, например, 0,72 и 0,007. Если вам нужно хранить числа, которые не являются целыми числами, вам нужен другой тип переменной. Вы можете использовать тип double или тип float. Вы устанавливаете эти типы переменных точно таким же образом: вместо использования слова intвы вводите doubleили float. Нравится:

float myFloat;
double myDouble;

( floatсокращение от «с плавающей запятой» и просто означает число с точкой на конце.)

Разница между ними заключается в размере чисел, которые они могут хранить. Например float, в вашем номере может быть до 7 цифр. Для doubles у вас может быть до 16 цифр. Чтобы быть более точным, вот официальный размер:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

float32-разрядное число и double64-разрядное число.

Дважды щелкните новую кнопку, чтобы получить код. Добавьте следующие три строки в код вашей кнопки:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

Остановите вашу программу и вернитесь в окно кодирования. Измените эту строку:

myDouble = 0.007;
myDouble = 12345678.1234567;

Запустите вашу программу и нажмите двойную кнопку. В окне сообщения правильно отображается номер. Добавьте еще один номер в конце, и C # снова округлит вверх или вниз. Мораль в том, что если вы хотите аккуратности, будьте осторожны с округлением!

29
19.02.2018 12:42:18
Упомянутая вами «точка что-то» обычно называется «дробной частью» числа. «Плавающая точка» не означает «число с точкой на конце»; но вместо этого «число с плавающей точкой» различает тип числа, в отличие от числа с «фиксированной точкой» (которое также может хранить дробное значение); разница в том, является ли точность фиксированной или плавающей. - Числа с плавающей запятой дают вам гораздо больший динамический диапазон значений (Мин. И Макс.) За счет точности, тогда как числа с фиксированной запятой дают вам постоянную степень точности за счет диапазона.
BrainSlugs83 16.09.2017 01:09:52
+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

Для получения дополнительной информации см .:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5

75
15.10.2018 04:34:35
Вы пропустили самое большое различие, которое является основанием, используемым для десятичного типа (десятичное число сохраняется как основание 10, все остальные перечисленные числовые типы являются основанием 2).
BrainSlugs83 14.03.2015 22:55:28
Диапазоны значений для Single и Double не отображаются правильно на изображении выше или в исходном сообщении на форуме. Поскольку мы не можем легко надписать текст здесь, используйте символ вставки: Single должен быть 10 ^ -45 и 10 ^ 38, а Double должен быть 10 ^ -324 и 10 ^ 308. Кроме того, MSDN имеет значение с диапазоном от -3,4x10 ^ 38 до + 3,4x10 ^ 38. Поиск MSDN для System.Single и System.Double в случае изменения ссылки. Единственный: msdn.microsoft.com/en-us/library/b1e65aza.aspx Двойной: msdn.microsoft.com/en-us/library/678hzkk9.aspx
deegee 22.06.2015 19:18:07
Десятичное число составляет 128 бит ... означает, что оно занимает 16 байтов, а не 12
user1477332 23.10.2018 03:29:23
  • float: от ± 1,5 x 10 ^ -45 до ± 3,4 x 10 ^ 38 (~ 7 значащих цифр
  • двойной: от ± 5,0 x 10 ^ -324 до ± 1,7 x 10 ^ 308 (15-16 значащих цифр)
  • десятичное число: ± 1,0 x 10 ^ -28 до ± 7,9 x 10 ^ 28 (28-29 значащих цифр)
16
2.04.2019 23:50:37
Разница не только в точности. - decimalфактически хранится в десятичном формате (в отличие от базы 2; поэтому он не будет терять или округлять цифры из-за преобразования между двумя числовыми системами); кроме того, decimalне имеет понятия специальных значений, таких как NaN, -0, ∞ или -∞.
BrainSlugs83 16.09.2017 01:19:22
@Mukesh Кумар, что значит сказать "значимые цифры"?
BdEngineer 18.10.2019 12:07:24

Для приложений, таких как игры и встроенные системы, где память и производительность имеют решающее значение, float обычно является числовым типом выбора, так как он быстрее и вдвое меньше двойного. Раньше целое число использовалось в качестве оружия, но производительность с плавающей запятой превысила целое число в современных процессорах. Десятичный прямо сейчас!

8
11.04.2016 22:52:05
Практически все современные системы, даже мобильные телефоны, имеют аппаратную поддержку double; и если ваша игра имеет даже простую физику, вы заметите большую разницу между double и float. (Например, вычисляя скорость / трение в простом клоне астероидов, удвоения позволяют ускорению течь гораздо более плавно, чем плавать. - Кажется, это не должно иметь значения, но это полностью имеет значение.)
BrainSlugs83 16.09.2017 01:22:47
Двойные числа также удваивают размер чисел с плавающей запятой, что означает, что вам нужно прожевать вдвое больше данных, что снижает производительность вашего кэша. Как всегда, измерьте и действуйте соответственно.
yoyo 22.09.2017 17:53:08

Переменные типа Decimal, Double и Float отличаются тем, как они хранят значения. Точность является основным отличием, когда float - это тип данных с плавающей запятой одинарной точности (32 бита), double - тип данных с плавающей запятой двойной точности (64 бита), а decimal - тип данных 128-битной плавающей запятой.

Float - 32 бита (7 цифр)

Двойной - 64 бит (15-16 цифр)

Десятичное число - 128 бит (28-29 значащих цифр)

Подробнее о ... разнице между десятичным, плавающим и двойным

7
13.01.2015 12:56:35

Основным отличием каждого из них является точность.

floatэто 32-bitчисло, doubleэто 64-bitчисло и decimalэто 128-bitчисло.

3
6.06.2015 08:07:02

Никто не упомянул, что

В настройках по умолчанию Floats (System.Single) и double (System.Double) никогда не будут использовать проверку переполнения, в то время как Decimal (System.Decimal) всегда будет использовать проверку переполнения.

я имею в виду

decimal myNumber = decimal.MaxValue;
myNumber += 1;

выдает OverflowException .

Но это не так:

float myNumber = float.MaxValue;
myNumber += 1;

&

double myNumber = double.MaxValue;
myNumber += 1;
35
15.04.2015 13:55:10
float.MaxValue+1 == float.MaxValue, просто как decimal.MaxValue+0.1D == decimal.MaxValue. Возможно, вы имели в виду что-то подобное float.MaxValue*2?
supercat 14.01.2015 00:21:28
@supercar Но это не правда, что десятичный. MaxValue + 1 == десятичный. MaxValue
GorkemHalulu 14.01.2015 06:12:08
@supercar decimal.MaxValue + 0.1m == decimal.MaxValue ok
GorkemHalulu 14.01.2015 06:19:45
System.DecimalБросает исключение как раз перед его становится не в состоянии различать целые единицы, но если приложение должно иметь дело, например , с долларами и центами, что может быть слишком поздно.
supercat 14.01.2015 16:15:01

Я не буду повторять тонны хорошей (и некоторой плохой) информации, на которую уже даны ответы в других ответах и ​​комментариях, но я отвечу на ваш дополнительный вопрос с подсказкой:

Когда кто-нибудь будет использовать один из них?

Используйте десятичную для подсчитанных значений

Используйте float / double для измеренных значений

Некоторые примеры:

  • деньги (мы считаем деньги или измеряем деньги?)

  • расстояние (мы считаем расстояние или измеряем расстояние? *)

  • баллы (мы считаем баллы или измеряем баллы?)

Мы всегда считаем деньги и никогда не должны их измерять. Мы обычно измеряем расстояние. Мы часто считаем счет.

* В некоторых случаях, что я бы назвал номинальным расстоянием , мы действительно можем рассчитывать расстояние. Например, возможно, мы имеем дело со знаками стран, которые показывают расстояния до городов, и мы знаем, что на этих расстояниях никогда не бывает больше одной десятичной цифры (ххх.х км).

48
22.04.2016 15:18:17
Мне очень нравится этот ответ, особенно вопрос "мы считаем или измеряем деньги?" Однако, кроме денег, я не могу думать ни о чем, что «считается», а не является просто целым числом. Я видел некоторые приложения, которые используют десятичные просто потому, что в double слишком мало значащих цифр. Другими словами, можно использовать десятичную дробь, потому что в C # нет четверного типа en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
John Henckel 4.04.2019 18:55:33

Проблема со всеми этими типами заключается в том, что существует определенная неточность И что эта проблема может возникать с небольшими десятичными числами, как в следующем примере

Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1

If fMean - fDelta < fLimit Then
    bLower = True
Else
    bLower = False
End If

Вопрос: Какое значение содержит переменная bLower?

Ответ: На 32-битной машине bLower содержит TRUE !!!

Если я заменю Double на Decimal, bLower будет содержать FALSE, что является хорошим ответом.

В двойном, проблема в том, что fMean-fDelta = 1.09999999999, что ниже, чем 1.1.

Предостережение: я думаю, что та же самая проблема, безусловно, может существовать для другого числа, потому что десятичная дробь - это только двойное число с более высокой точностью, а точность всегда имеет предел.

Фактически, Double, Float и Decimal соответствуют двоичному десятичному числу в COBOL!

К сожалению, другие числовые типы, реализованные в COBOL, не существуют в .Net. Для тех, кто не знает COBOL, существует в COBOL следующий числовой тип

BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte) 
5
23.02.2017 13:05:31

Простыми словами:

  1. Переменные типа Decimal, Double и Float отличаются тем, как они хранят значения.
  2. Точность является основным отличием (обратите внимание, что это не единственная разница), где float - это тип данных с плавающей запятой одинарной точности (32 бита), double - тип данных с плавающей запятой двойной точности (64 бита), а десятичный - 128-битный тип данных с плавающей точкой.
  3. Сводная таблица:

/==========================================================================================
    Type       Bits    Have up to                   Approximate Range 
/==========================================================================================
    float      32      7 digits                     -3.4 × 10 ^ (38)   to +3.4 × 10 ^ (38)
    double     64      15-16 digits                 ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
    decimal    128     28-29 significant digits     ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
Вы можете прочитать больше здесь , Float , Double и Decimal .

5
10.02.2018 09:19:02
Что добавляет этот ответ, который еще не включен в существующие ответы? Кстати, ваше «или» в десятичной строке неверно: косая черта на веб-странице, с которой вы копируете, указывает на разделение, а не на альтернативу.
Mark Dickinson 10.02.2018 12:15:36
И я бы решительно оспаривал, что точность - это главное отличие. Основное отличие - это основа: десятичная с плавающей точкой и двоичная с плавающей точкой. Именно эта разница Decimalподходит для финансовых приложений и является основным критерием при выборе между Decimalи Double. DoubleНапример , редко бывает недостаточно точности для научных приложений (и Decimalчасто не подходит для научных приложений из-за ограниченного диапазона).
Mark Dickinson 10.02.2018 12:28:21
  • Десятичное число 128 бит (28-29 значащих цифр) В финансовых приложениях лучше использовать типы десятичных чисел, поскольку они обеспечивают высокий уровень точности и позволяют легко избежать ошибок округления. Используйте десятичную для нецелочисленной математики, где требуется точность (например, деньги и валюта)

  • Двойные 64-битные (15-16 цифр) двойные типы, вероятно, являются наиболее обычно используемым типом данных для реальных значений, за исключением обработки денег. Используйте double для нецелочисленной математики, где не требуется самый точный ответ.

  • 32-разрядное число с плавающей запятой (7 цифр). Используется в основном в графических библиотеках, поскольку очень высоки требования к вычислительной мощности, а также используются ситуации, которые могут выдержать ошибки округления.

Decimalsнамного медленнее, чем double/float.

Decimalsи Floats/Doublesне может быть сравнен без броска, тогда как Floatsи Doublesможет.

Decimals также разрешить кодирование или конечные нули.

1
14.12.2019 12:16:36

Чтобы определить десятичные, плавающие и двойные в .Net (c #)

Вы должны упомянуть значения как:

Decimal dec = 12M/6;
Double dbl = 11D/6;
float fl = 15F/6;

и проверьте результаты.

И байты, занятые каждым

Float - 4
Double - 8
Decimal - 12
0
17.01.2020 11:26:59