Разница между десятичной, плавающей и двойной в .NET?
В чем разница между decimal
, float
и double
в .NET?
Когда кто-нибудь воспользуется одним из них?
- Почему бы не использовать Double или Float для представления валюты?
- В MATLAB переменные ДЕЙСТВИТЕЛЬНО двойной точности по умолчанию?
- Как изменить поплавок на наименьший приращение (или близко к нему)?
- Float / double precision в режимах отладки / выпуска
- Является ли плавающая точка == когда-либо ОК?
- pow (), кажется, отсутствует здесь
- Меню поддержки поддержки Android Design Library (FAB)
- Равновесие и допуски с плавающей точкой
- Почему (360/24) / 60 = 0 ... в Java
- Сравнение с плавающей точкой
- Как мне сделать сравнение с плавающей запятой?
- double или float, что быстрее?
- Должны ли мы обычно использовать float-литералы для поплавков вместо простых двойных литералов?
float
и double
– это типы плавающих двоичных точек . Другими словами, они представляют собой число, подобное этому:
10001.10010110011
Двоичный номер и местоположение двоичной точки кодируются в пределах значения.
decimal
– тип с плавающей запятой . Другими словами, они представляют собой число, подобное этому:
12345.65789
Опять же, число и местоположение десятичной точки оба закодированы внутри значения – это то, что делает decimal
типом еще тип с плавающей точкой вместо типа фиксированной точки.
Важно отметить, что люди используются для представления нецелых чисел в десятичной форме и ожидают точных результатов в десятичных представлениях; не все десятичные числа точно представлены в двоичной с плавающей запятой – 0,1, например, поэтому, если вы используете двоичное значение с плавающей запятой, вы фактически получите приближение к 0,1. Вы также получите приближения при использовании плавающей десятичной точки – результат деления 1 на 3 не может быть точно представлен, например.
Что касается того, что использовать, когда:
-
Для значений, которые являются «естественно точными десятичными знаками», полезно использовать
decimal
. Это обычно подходит для любых понятий, изобретенных людьми: финансовые показатели являются наиболее очевидным примером, но есть и другие. Рассмотрим, например, оценку дайверам или фигуристам. -
Для значений, которые являются более артефактами природы, которые в действительности не могут быть точно измерены,
float
/double
более подходят. Например, научные данные обычно представляются в этой форме. Здесь исходные значения не будут «децимально точными» для начала, поэтому для ожидаемых результатов не важно поддерживать «десятичную точность». Плавающие двоичные точечные типы намного быстрее работают, чем десятичные.
Точность – главное различие.
Float – 7 цифр (32 бит)
Двойной -15-16 цифр (64 бит)
Decimal -28-29 значащих цифр (128 бит)
Десятичные числа имеют гораздо более высокую точность и обычно используются в финансовых приложениях, требующих высокой степени точности. Десятичные числа намного медленнее (до 20 раз в некоторых тестах), чем двойной / плавающий.
Десятичные числа и поплавки / парные пары не могут сравниваться без броска, тогда как Floats and Doubles могут. Десятичные числа также допускают кодирование или конечные нули.
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
Десятичная структура строго ориентирована на финансовые расчеты, требующие точности, которые относительно нетерпимы к округлению. Десятичные числа не подходят для научных приложений, однако по нескольким причинам:
- Определенная потеря точности приемлема во многих научных расчетах из-за практических пределов измеряемой физической проблемы или артефакта. Потеря точности не приемлема в финансах.
- Десятичное число (намного) медленнее, чем float и double для большинства операций, в первую очередь потому, что операции с плавающей запятой выполняются в двоичном формате, тогда как десятичный материал выполняется в базе 10 (т.е. поплавки и удваиваются обрабатываются оборудованием FPU, например MMX / SSE , тогда как десятичные числа вычисляются в программном обеспечении).
- Decimal имеет недопустимо меньший диапазон значений, чем двойной, несмотря на то, что он поддерживает больше цифр точности. Поэтому Decimal нельзя использовать для представления многих научных ценностей.
для получения дополнительной информации вы можете пойти в источник этой картины:
float
7 цифр точности
double
имеет около 15 цифр точности
decimal
цифра имеет около 28 цифр точности
Если вам нужна более высокая точность, используйте double вместо float. В современных процессорах оба типа данных имеют почти такую же производительность. Единственное преимущество использования float – они занимают меньше места. Практически важно, только если у вас их много.
Я нашел это интересным. Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой
Никто не упомянул, что
В настройках по умолчанию 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;
Я не буду повторять тонны хорошей (и некорректной) информации, на которую уже ответил ответ в других ответах и комментариях, но я отвечу на ваш следующий вопрос с подсказкой:
Когда кто-нибудь воспользуется одним из них?
Использовать десятичное значение для подсчитанных значений
Используйте float / double для измеренных значений
Некоторые примеры:
-
деньги (мы считаем деньги или измеряем деньги?)
-
расстояние (мы рассчитываем расстояние или измеряем расстояние?)
-
(подсчитываем ли мы оценки или оцениваем баллы?)
Мы всегда считаем деньги и никогда не должны их измерять. Обычно мы измеряем расстояние. Мы часто подсчитываем баллы.
* В некоторых случаях, что я бы назвал номинальным расстоянием , мы можем действительно хотеть «подсчитать» расстояние. Например, возможно, мы имеем дело со знаками страны, которые показывают расстояния до городов, и мы знаем, что эти расстояния никогда не имеют более одной десятичной цифры (xxx.x км).
- Двойной и float можно разделить на целые числа без исключения как для компиляции, так и для времени выполнения.
- Десятичное число нельзя делить на целое число. Компиляция всегда будет терпеть неудачу, если вы это сделаете.
Типы переменных Decimal, Double и Float отличаются тем, что они сохраняют значения. Точность – основное отличие, когда float представляет собой тип данных с плавающей точкой с одной точностью (32 бит), double – это тип данных с плавающей запятой двойной точности (64 бит), а десятичный – это тип данных с плавающей точкой с 128-битной точкой.
Float – 32 бит (7 цифр)
Двойной – 64 бит (15-16 цифр)
Десятичная – 128 бит (28-29 значащих цифр)
Основное различие заключается в том, что Floats and Doubles представляют собой двоичные типы с плавающей запятой, а Decimal будет хранить значение в виде типа с плавающей запятой. Таким образом, Decimals имеют гораздо более высокую точность и обычно используются в денежных (финансовых) или научных приложениях расчета, которые требуют высокой степени точности. Но по производительности разумные Десятичные числа медленнее, чем двойные и плавающие типы.
Decimal может 100% точно представлять любое число в пределах точности десятичного формата, тогда как Float и Double, не могут точно представлять все числа, даже числа, которые находятся в пределах их соответствующих форматов.
Десятичная дробь
В случае финансовых приложений или научных расчетов лучше использовать десятичные типы, потому что это дает вам высокий уровень точности и легко избежать ошибок округления
двойной
Двойные типы, вероятно, являются наиболее обычно используемым типом данных для реальных значений, за исключением обработки денег.
терка
Он используется в основном в графических библиотеках, потому что очень высокие требования к вычислительной мощности, а также используются ситуации, которые могут выдержать ошибки округления.
Целые числа, как уже упоминалось, являются целыми числами. Они не могут хранить точку, например .7, .42 и .007. Если вам нужно хранить числа, которые не являются целыми числами, вам нужен другой тип переменной. Вы можете использовать тип double или float. Вы устанавливаете эти типы переменных точно так же: вместо использования слова int
вы вводите double
или float
. Как это:
float myFloat; double myDouble;
( float
подходит для «плавающей запятой» и просто означает число с точкой что-то в конце.)
Разница между ними – это размер чисел, которые они могут удерживать. Для float
вы можете иметь до 7 цифр в своем номере. Для double
s вы можете иметь до 16 цифр. Если быть более точным, вот официальный размер:
float: 1.5 × 10^-45 to 3.4 × 10^38 double: 5.0 × 10^-324 to 1.7 × 10^308
float
– 32-разрядное число, а double
– 64-разрядное число.
Дважды щелкните по новой кнопке, чтобы получить код. Добавьте в код кнопки следующие три строки:
double myDouble; myDouble = 0.007; MessageBox.Show(myDouble.ToString());
Остановите свою программу и вернитесь в окно кодирования. Измените эту строку:
myDouble = 0.007; myDouble = 12345678.1234567;
Запустите программу и нажмите двойную кнопку. В поле сообщения правильно отображается номер. Добавьте еще один номер в конец, и C # снова округляется вверх или вниз. Мораль – если вы хотите точности, будьте осторожны с округлением!
Это была интересная тема для меня, так как сегодня у нас просто была неприятная небольшая ошибка, касающаяся decimal
чисел с меньшей точностью, чем float
.
В нашем коде C # мы считываем числовые значения из электронной таблицы Excel, преобразуя их в 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 (), значение out); // вернет 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
имеет меньшую точность, чем decimal
, это фактически обеспечило бы признание небольших чисел. По какой-то причине double.TryParse
действительно смог получить такие маленькие числа, тогда как decimal.TryParse
установил бы их в ноль.
Странный. Очень странно.
float ~ ± 1,5 x 10-45 до ± 3,4 × 1038 ——– 7 цифр
двойной ~ ± 5,0 × 10-324 ± 1,7 × 10308 —— 15 или 16 цифр
десятичная ~ ± 1,0 × 10-28 до ± 7,9 × 1028 ——– 28 или 29 цифр
Для приложений, таких как игры и встроенные системы, где важна память и производительность, float обычно является числовым типом выбора, поскольку он быстрее и вдвое меньше двойного. Целые были предпочтительным оружием, но производительность с плавающей запятой превосходила целое число в современных процессорах. Десятичное право!
Типы переменных Decimal, Double и Float отличаются тем, что они сохраняют значения. Точность – основное отличие, когда float представляет собой тип данных с плавающей точкой с одной точностью (32 бит), double – это тип данных с плавающей запятой двойной точности (64 бит), а десятичный – это тип данных с плавающей точкой с 128-битной точкой.
Float – 32 бит (7 цифр)
Двойной – 64 бит (15-16 цифр)
Десятичная – 128 бит (28-29 значащих цифр)
Подробнее о … разница между десятичным, плавающим и двойным
Проблема со всеми этими типами заключается в том, что существует некоторая неточность И эта проблема может возникать с небольшими десятичными числами, как в следующем примере
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.
Осторожно: я думаю, что такая же проблема может существовать и для другого числа, потому что Decimal является только двойным с более высокой точностью, и точность всегда имеет предел.
Фактически, Double, Float и Decimal соответствуют BINARY десятичному значению в 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)
Основное различие между каждым из них – точность.
float
– 32-bit
число, double
– это 64-bit
число, а decimal
число – 128-bit
число.
Простыми словами:
- Типы переменных Decimal, Double и Float отличаются тем, что они сохраняют значения.
- Точность – основное различие (обратите внимание, что это не единственная разница), где float – это тип данных с плавающей точкой с одной точностью (32 бит), double – это тип данных с плавающей точкой с двойной точностью (64 бит), а десятичный – это 128-битный тип данных с плавающей точкой.
- Сводная таблица:
/========================================================================================== 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 .