Decimal(19,4) или Decimal (19.2) - что я должен использовать?

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

Почему 4 по шкале? Почему не 2?

возможно, я упускаю потенциальную проблему расчета по дороге?

4 ответов


во-первых - вы получаете некоторые ошибочные советы от других ответов. Obseve следующее (64-разрядная ОС на 64-разрядной архитектуре):

declare @op1 decimal(18,2) = 0.01
       ,@op2 decimal(18,2) = 0.01;

select result = @op1 * @op2;

result
---------.---------.---------.---------
0.0001

(1 row(s) affected)

обратите внимание на количество подчеркиваний под заголовком - 39 в целом. (Я изменил каждую десятую на точку, чтобы облегчить подсчет.) Этого точно достаточно для 38 цифр (максимально допустимых и по умолчанию на 64-битном процессоре) плюс десятичная точка на дисплее. Хотя оба операнда были объявлены как decimal (18,2) в расчет производился, и сообщалось, в decimal (38,4) тип данных. (Я запускаю SQL 2012 на 64-разрядной машине - некоторые детали могут отличаться в зависимости от архитектуры машины и ОС.)

поэтому ясно, что точность не теряется. Наоборот, может произойти только переполнение, а не потеря точности. Это прямое следствие того, что все вычисления на десятичных операндах выполняются как целочисленная арифметика. Иногда вы будете видеть артефакты этого в intelli-sense когда тип промежуточных полей decimal тип сообщается какint вместо.

Рассмотрим пример выше. Оба операнда имеют тип decimal (18,2) и хранятся как целые числа со значением 1 со шкалой 2. При умножении произведение все равно 1, но шкала оценивается путем добавления шкал, чтобы создать результат целочисленного значения 1 и шкалы 4, который является значением 0.0001 и типа decimal (18,4), хранится как целое число со значением 1 и шкале 4.

читай последний абзац еще раз.

промойте и повторите еще раз.

на практике, на 64-битной машине и ОС, это фактически хранится и переносится как тип *decimal (38,4), потому что вычисления выполняются на CPU, где дополнительные биты свободны.

чтобы вернуться к вашему вопросу-все основные валюты мира (о которых я знаю) только требуется 2 знака после запятой, но есть несколько, где требуется 4, и есть финансовые операции, такие как валютные операции и продажи облигаций, где 4 знака после запятой установлены законом. При разработке деньги тип данных Microsoft, по-видимому, выбрал максимальный масштаб, который может потребоваться, а не обычный требуемый масштаб. Учитывая, как мало транзакций и корпораций на самом деле требуют точности больше 19 цифр, это кажется в высшей степени разумным.

Если у вас есть:

  1. высокое ожидание только работы с основными валютами (которые в настоящее время требуют только 2 цифры шкалы); и
  2. нет ожиданий иметь дело с транзакциями, которые уполномочены законом требовать 4 цифры шкалы

тогда вы будете в безопасности, чтобы использовать тип decimal со шкалой 2 (например,decimal (19,2) или decimal (18,2) или decimal (38,2)) вместо денег. Это облегчит некоторые из ваших преобразований и, учитывая приведенные выше предположения, не будет стоить. Типичный случай, когда эти предположения are met находится в системе учета GL или Субкниги отслеживания транзакций до копейки. Тем не менее, система торговли акциями или облигациями не отвечает эти предположения, потому что 4 цифры шкалы санкционированы законом в этом случае.

способ различить два случая заключается в том, сделки зарегистрированы в копеек или проц, которые требуют только 2 цифры масштаба, или в базисных пунктов, которые требуют 4 цифры шкалы.

Если вы не уверены в том, какой случай относится к вашему программному обстоятельству, проконсультируйтесь с вашим контроллером или финансовым директором относительно юридических требований и требований GAAP для вашего приложения. (С)он сможет дать вам окончательный совет.


такие вещи, как цены на газ будут использовать дополнительные "данные" позиции. Вы видели газ по $1.959 за галлон, верно?


при использовании decimal это зависит от вас, как вы хотите использовать в соответствии с вашими бизнес-требованиями.

но когда вы будете использовать тип данных Money в sql по умолчанию, он хранит 4 знака после запятой.


в SQL 19-это количество целых чисел, 4 - Количество десятичных знаков.

Если у вас есть только 2 десятичных знака, и вы храните, возможно, результат некоторых вычислений, что приводит к более чем 2 десятичных знаков, theres "нет способа" сохранить эти дополнительные десятичные знаки.

некоторые валюты работают с более чем 2 десятичными знаками.

используйте тип данных decimal, а не money.