За кулисами, что происходит с типом десятичного значения в C # /. NET? - PullRequest
18 голосов
/ 21 июля 2010

Как реализован тип decimal?

Обновление

  • Это 128-битный тип значения (16 байтов)
  • 1 знаковый бит
  • 96 бит (12 байт) для мантиссы
  • 8 бит для показателя степени
  • оставшиеся биты (23 из них!) Установлены в 0

Спасибо! Я буду использовать 64-битную длину с моей собственной предполагаемой шкалой.

Ответы [ 6 ]

8 голосов
/ 21 июля 2010

десятичное число с плавающей точкой статья в Википедии со специальной ссылкой на эту статью о System.Decimal.

Десятичное число сохраняется в 128 битах, дажехотя только 102 строго необходимы.Десятичное число удобно рассматривать как три 32-разрядных целых числа, представляющих мантиссу, а затем одно целое число, представляющее знак и показатель степени.Верхний бит последнего целого числа является знаковым битом (обычным образом, с битом, установленным (1) для отрицательных чисел), а биты 16-23 (младшие биты старшего 16-битного слова) содержат показатель степени.Все остальные биты должны быть очищены (0).Это представление задается с помощью decimal.GetBits (decimal), который возвращает массив из 4-х дюймов.

1 голос
/ 21 июля 2010

Из языковых спецификаций C # :

Тип decimal - это 128-битный тип данных, подходящий для финансовых и денежных расчетов.
decimalТип может представлять значения в диапазоне от 1,0 × 10 -28 до приблизительно 7,9 × 10 28 с 28-29 значащими цифрами.

Конечный набор значений типа decimal имеют вид (–1) с × c × 10 - e , гдезнак s равен 0 или 1, коэффициент c равен 0 ≤ c <2 <sup>96 , а шкала e таково, что 0 ≤ e ≤ 28.
Тип decimal не поддерживает нули со знаком, бесконечности или числа NaN.decimal представляется в виде 96-битного целого числа, масштабируемого степенью десяти.Для десятичных чисел с абсолютным значением менее 1,0 м значение является точным с точностью до десятичного знака 28 th , но не дальше.

Для десятичных знаков с абсолютным значением, превышающим или равным 1,0 м, это значение является точным до 28 или 29 цифр.В отличие от типов данных float и double десятичные дробные числа, такие как 0,1, могут быть представлены точно в десятичном представлении.В представлениях float и double такие числа часто представляют собой бесконечные дроби, что делает эти представления более склонными к ошибкам округления.

Если один из операндов двоичного оператора имеет тип decimalтогда другой операнд должен иметь целочисленный тип или тип decimal.Если присутствует операнд целочисленного типа, он преобразуется в decimal до выполнения операции.

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

Если десятичная арифметическая операция выдает значение, меньшее или равное 5 × 10 -29 в абсолютном значении,результат операции становится равным нулю.Если десятичная арифметическая операция приводит к результату, который слишком велик для формата decimal, выдается System.OverflowException.

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

1 голос
/ 21 июля 2010

Как описано на странице десятичной структуры MSDN в http://msdn.microsoft.com/en-us/library/system.decimal(VS.80).aspx:

Двоичное представление десятичного значения состоит из 1-битного знака, 96-битного целого числа и используемого коэффициента масштабированияразделить 96-битное целое число и указать, какая его часть является десятичной дробью.Коэффициент масштабирования - это неявно число 10, возведенное в степень в диапазоне от 0 до 28. Следовательно, двоичное представление десятичного значения имеет вид ((от -296 до 296) / 10 (от 0 до 28)), где-296-1 равно MinValue, а 296-1 равно MaxValue.

Коэффициент масштабирования также сохраняет любые конечные нули в десятичном числе.Конечные нули не влияют на значение десятичного числа в арифметических или сравнительных операциях.Однако конечные нули могут быть обнаружены методом ToString, если применяется соответствующая строка формата.

0 голосов
/ 21 июля 2010

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

Простое объяснение здесь http://csharpindepth.com/Articles/General/Decimal.aspx

0 голосов
/ 21 июля 2010

Ключевое слово decimal обозначает 128-битный тип данных.

Источник

Двоичное представление десятичного значения состоит из 1-разрядного знака, 96-разрядного целого числа и масштабного коэффициента, используемого для деления 96-разрядного целого числа и указания, какая его часть является десятичной дробью. Коэффициент масштабирования - это неявно число 10, возведенное в степень в диапазоне от 0 до 28. Следовательно, двоичное представление десятичного значения имеет вид ((от -296 до 296) / 10 (от 0 до 28)), где -296-1 равно MinValue, а 296-1 равно MaxValue.

Источник

0 голосов
/ 21 июля 2010

Из "CLR via C #" 3-го издания Дж. Рихтера:

128-битная высокая точность значение с плавающей точкой, обычно используемое для финансовые расчеты, в которых ошибки округления недопустимы. из 128 бит, 1 бит представляет знак значения, 96 бит представляют само значение, и 8 бит представляют сила 10 для деления 96-битного значение по (может быть от 0 до 28). Остальные биты не используются.

...