Почти Эквивалент2сКомплемент или BigDecimal Scaling - PullRequest
0 голосов
/ 12 января 2009

Использование Java:

Чем больше я читаю при сравнении значений с плавающей запятой, тем больше я теряюсь. В случае валюты, которая обычно округляется, что вы предпочитаете, используя Epsilon или сравнение большого десятичного числа с масштабированием?

Например, ваши данные будут в диапазоне от 0,00 до 49 999,99?

Ответы [ 2 ]

1 голос
/ 12 января 2009

Кроме того, при обработке валюты нет причины, по которой вы не можете просто хранить целое число, представляющее центы, а не доллары, так что вы фактически получаете представление с фиксированной запятой. например, $ 4,09 сохраняется как 409 и так далее. (Вы также можете хранить десятые доли цента , т. Е. 4090 или другую постоянную дробную точность.) Вы сможете добавлять и вычитать бесконечное количество раз, не теряя точности.

Для таких вычислений, как проценты, выполните вычисления с числами с плавающей запятой, а затем просто округлите до необходимой точности перед сохранением. Сам расчет процентов будет иметь необходимую точность, и вы будете последовательно округлять до одного и того же числа десятичных разрядов каждый период, что обычно является тем, что вам нужно в финансовых расчетах (я никогда не видел учреждения, которое действительно хочет отслеживать 0,0000 один период оплаты до другого - по юридическим причинам они будут округлять свои книги с определенной точностью.)

Обычное подписанное int хранение центов позволит вам получить до 21 474 836,47 долларов. Вы можете использовать long для хранения $ 92 233 720 368 547 758,07. Для работы с более чем квадриллионами денежных единиц (представляющих бюджет США в долларах Зимбабве?) Используйте BigDecimal.

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

1 голос
/ 12 января 2009

Для диапазона данных от 0 до 50000 с 2 десятичными цифрами я бы использовал встроенные типы с эпсилоном.

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

Позвольте мне объяснить: допустим, у вашего float 17 значащих цифр. Это означает, что ваша ошибка для номеров до 49999,99 может быть около 0,000000000001. Вам нужно будет добавить около 10 миллиардов чисел, чтобы эта кумулятивная ошибка достигла одного цента Умножение и деление накапливают эту ошибку быстрее, но это все равно займет довольно много времени.

Если вы не понимаете, как это работает (а производительность не является основной и конечной в вашем приложении), используйте BigDecimal для безопасности. Встроенные типы должны быть намного быстрее.

...