Почему BigDecimal возвращает странное значение?

У нас были те же проблемы с конечной точкой REST, и мы в большой степени полагались (и вроде) на Graphql, поэтому мы решили создать вспомогательную библиотеку.

https://github.com/lionixevolve/GraphQLSuiteCRM

До сих пор мы использовали это в 5 небольших проектах (5M таблиц записей с сотнями пользователей) .

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

В настоящее время он использует тонкий каркас, который позволяет вам писать свои собственные функции.

Я активен в репозитории github, откройте вопрос, если у вас возникнут проблемы.

15
задан the Tin Man 25 December 2012 в 06:14
поделиться

5 ответов

Вы правы, BigDecimal должен правильно его хранить, мое лучшее предположение:

  • BigDecimal правильно хранит значение
  • При передаче в функцию форматирования строки BigDecimal приводится в качестве значения с плавающей точкой с меньшей точностью, создавая ... 02.
  • Если сравнивать непосредственно с поплавком, то поплавок имеет дополнительный десятичный знак, намного превосходящий 20, которые вы видите (классические поплавки нельзя сравнивать по поведению).

В любом случае вы вряд ли получите точные результаты, сравнивая поплавок в BigDecimal.

8
ответ дан 1 December 2019 в 02:10
поделиться

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

a.to_s('F')

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

gem install money
9
ответ дан 1 December 2019 в 02:10
поделиться

, как сказал Дэвид, BigDecimal правильно хранит его

 p (BigDecimal('1876.8') * 100000000000000).to_i

возвращает 187680000000000000

, так что да, форматирование строк разрушает его

3
ответ дан 1 December 2019 в 02:10
поделиться

В Mac OS X я использую ruby ​​1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9]

irb(main):004:0> 1876.8 == BigDecimal('1876.8') => true

Однако, будучи Ruby, я думаю, Вы должны думать с точки зрения сообщений, отправляемых объектам. Что это вам возвращает:

BigDecimal('1876.8') == 1876.8

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

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

1
ответ дан 1 December 2019 в 02:10
поделиться

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

2
ответ дан 1 December 2019 в 02:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: