Почему приложения обычно не используют int для внутреннего представления значений валют? - PullRequest
12 голосов
/ 18 марта 2011

Почему приложения обычно не используют целочисленный тип данных (например, int или long в C ++ / Java / C #) для внутреннего представления значений валюты, в отличие от использования типа данных с плавающей точкой (float, double) или что-то вроде Java BigDecimal?

Например, если я пишу приложение на Java и у меня есть переменная, в которой я хочу представить действительное значение в долларах США (нет необходимости представлять доли копеек), я могу объявить значение int, которое представляет количество центов. Например, значение «$ 1,00» будет представлено как 100. Это кажется хорошей альтернативой использованию double (см. Вопрос Почему бы не использовать Double или Float для представления валюты? ) или BigDecimal (который является более тяжелым объектом, чем простой примитив int).

Очевидно, что целочисленное значение необходимо будет «перевести» (т. Е. От 100 до «1 долл.» Или «1,00 долл.») Перед его отображением пользователю или при вводе пользователем значения валюты, но это не делает этого. Это кажется значительно более обременительным, чем форматирование double или BigDecimal для отображения.

Почему этот подход не является лучшей практикой среди приложений, которым не нужно представлять доли центов (или эквивалент в других типах валют)?

Ответы [ 3 ]

10 голосов
/ 18 марта 2011

Почему приложения обычно не используют [целые числа] для внутреннего представления значений валюты?

  1. Это не способствует простому кодированию.$ 1,10 переводится в 110 ¢.Хорошо, но как насчет того, когда вам нужно рассчитать налог (т. Е. 1,10 * 4,225% - налоговая ставка Миссури, которая составляет 0,046475 долл. США).Чтобы сохранить все деньги в целых числах, вам также необходимо преобразовать налог с продаж в целое число (4225), для чего потребуется преобразовать 110 ¢ далее в 11000000. Математическое значение может быть 11000000 * 4225/100000 = 464750. Этопроблема, так как теперь у нас есть значения в долях центов (11000000 и 464750 соответственно).Все это ради хранения денег в виде целых чисел.

  2. Поэтому проще думать и кодировать в терминах национальной валюты.В Соединенных Штатах это было бы в долларах с центами, являющимися десятичной дробью (то есть 1,10 $).Кодирование в терминах 110 ¢ не так естественно.Использование чисел с плавающей точкой base-10 (таких как BigDecimal в Java и Decimal в .NET) обычно достаточно точно для значений валют (по сравнению с числами с плавающей точкой base-2, такими как Float и Double).

Почему этот подход не является лучшей практикой среди приложений, которым не нужно представлять доли центов (или эквивалент в других типах валют)?

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

5 голосов
/ 18 марта 2011

Целочисленные типы

Неправильно использовать большинство целочисленных типов данных для представления валют из-за:

  • очень ограниченное представимое значение диапазон в отношении общих применений;
  • наложение дополнительная нагрузка на обработку дробные значения .

В частности, ограниченный диапазон значений может быть серьезной проблемой с более коротким целым типом. Давайте рассмотрим общее 32-разрядное целое число со знаком (обычно int):

  • диапазон значений от прибл. От -2,15 млрд. До +2,15 млрд. - это само по себе не вариант для любого учета / банковского дела / серьезного финансового использования;
  • когда для представления дробной части используются только две последние цифры, диапазон сокращается до -21,5 миллионов до +21,5 миллионов ;
  • в случае, если умножение должно работать (не говоря о вычислениях смешанной точности), диапазон уменьшается еще больше.

С 64-разрядным целым числом со знаком (обычно long) вы можете считать до 92 тысяч триллионов. Когда мы думаем о мировой экономике, деньги исчисляются триллионами, поэтому это не разумный вариант.

Типы с плавающей точкой

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

Подходящие типы данных

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

  • диапазон представимых значений достаточно широк;
  • Точность может быть скорректирована путем округления в соответствии с требованиями расчета;
  • нет путаницы благодаря обработке естественных дробных значений;
  • точное представление десятичного числа.

И последнее, но не менее важное: подходящий тип данных сильно зависит от языка и его возможностей.

Другие проблемы

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

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

1 голос
/ 18 марта 2011

Я полагаю, что gnucash использует рациональное представление, хранящее числитель и знаменатель. У меня нет данных, чтобы сказать, что такое лучшая или распространенная практика. Преимущество с плавающей точкой заключается в целесообразности и недостатке в том, что она неточна. Лично я бы не использовал плавающую точку.

...