Вопрос

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

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

Это было полезно?

Решение

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

10001.10010110011

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

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

12345.65789

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

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

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

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

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

Другие советы

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

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

Двойные -15-16 цифр (64-разрядные)

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

Десятичные числа имеют гораздо более высокую точность и обычно используются в финансовых приложениях, которые требуют высокой степени точности. Десятичные дроби намного медленнее (в некоторых тестах до 20 раз), чем double / float.

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

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

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

  • Определенная потеря точности допустима во многих научных расчетах из-за практических ограничений измеряемой физической проблемы или артефакта.Потеря точности недопустима в финансах.
  • Decimal намного (намного) медленнее, чем float и double для большинства операций, в первую очередь потому, что операции с плавающей запятой выполняются в двоичном формате, тогда как десятичный материал выполняется в базе 10 (т. Е.числа с плавающей запятой и удвоения обрабатываются аппаратными средствами FPU, такими как MMX / SSE, в то время как десятичные дроби вычисляются программным путем).
  • Decimal имеет недопустимо меньший диапазон значений, чем double, несмотря на то, что он поддерживает большее количество цифр точности.Следовательно, десятичная дробь не может использоваться для представления многих научных значений.
+---------+----------------+---------+----------+---------------------------------------------+
| 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 / Форум / EN-US / csharpgeneral / резьба / 921a8ffc-9829-4145-bdc9-a96c1ec174a5

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

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

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

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

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

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

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

Используйте десятичную дробь для подсчитано ценности

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

Несколько примеров:

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

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

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

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

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

Никто не упоминал об этом

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

Я имею в виду

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

бросает Исключение OverflowException.

Но это не так:

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

&

double myNumber = double.MaxValue;
myNumber += 1;

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

float myFloat;
double myDouble;

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

Разница между ними заключается в размере чисел, которые они могут содержать. Для float в вашем номере может быть до 7 цифр. Для double вы можете иметь до 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 # снова округлит вверх или вниз. Мораль такова: если хочешь аккуратности, будь осторожен с округлением!

<Ол>
  • Double и float могут быть разделены на целое число ноль без исключения как во время компиляции, так и во время выполнения.
  • Десятичная дробь не может быть разделена на целое число ноль. Компиляция всегда будет неудачной, если вы это сделаете.
  • Для меня это была интересная тема, так как сегодня у нас только что произошла неприятная маленькая ошибка, касающаяся decimal имеющий меньшую точность, чем float.

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

    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 полностью утратил свою ценность.Одним из таких примеров является

    • Значение ячейки = 0.00006317592

    • Десятичный.Попробуйте проанализировать (значение ячейки.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 обладает меньшей точностью, чем decimal, это фактически гарантировало, что небольшие числа все равно будут распознаны.По какой - то причине, double.TryParse на самом деле был в состоянии получить такие небольшие числа, тогда как decimal.TryParse установил бы их равными нулю.

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

    • плавать:от ±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 значащих цифр)

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

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

    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) 
    

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

    <Ол>
  • Типы переменных Decimal, Double и Float отличаются тем, как они хранят значения.
  • Точность - это основное отличие (обратите внимание, что это не единственное отличие), где float - это плавающее значение с одинарной точностью (32 бита) тип данных point, 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 и десятичное число .

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

    float - это 32-разрядное число, double - это 64-разрядное число и десятичное число - это 128-битное число.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top