2015-02-03 2 views
0

Мы знаем, что использование float или double - это не тот вариант, где правильная точность необходима, и мы знаем, что BigDecimal служит этой цели, но мы также знаем, что она примерно в 100 раз медленнее обычных примитивных операций.Денежная точность в Java (не BigDecimal)

Теперь что нам делать, если скорость для нас важна, и нам действительно нужна точность?

Я попытался сохранить стоимость валюты в самой медленной единице и сохранить ее конверсию, как 1 BTC = 100000000 сатоши, но после нескольких экспериментов ясно, что вы просто не сможете хранить 100BTC в длине, превышает максимально возможное значение. Да, есть возможность жертвовать точностью, как хранение microBTC и т. Д., Но проблема более глобальная, как мы разрабатываем такую ​​вещь с примитивами?

+2

Я не нашел 'BigDecimal' против примитивов, чтобы стать узким местом. Вы уверены, что это слишком медленно для ваших нужд? – Kon

+0

Да, простой микро-тест показывает, что, кроме того, очевидно, что вы создаете неизменяемый объект каждый раз, он просто не может быть узким местом, когда вам нужна скорость ... – vach

+0

Я могу найти статью, где экспертный Java-разработчик HFT заявляет, что BigDecimal сосет как 100 раз по сравнению с примитивными типами – vach

ответ

5

Как Д.Е.Кнут хорошо задокументировал в своем томе 2 «Искусство программирования», реализующий арифметику с произвольной точностью, не является «черным искусством» - см. Главу «Семинумерные алгоритмы». Я прошел через это, следуя потребностям в выполнении вычислений COBOL (так: не только целые числа).

Кроме того, создание рабочего файла BigInteger или BigDecimal без повторного создания объекта для каждого нового результата работы является опцией. Да, это означает работу, но если вы действительно думаете, что вам это нужно ...

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

+0

* Семинумерные алгоритмы * - это название всего тома, а не одна глава. Глава, на которую вы ссылаетесь, озаглавлена ​​* Арифметика. * – EJP

1

варианта:

BigDecimal - Точная и эффективная - медленнее, чем примитивы, но, вероятно, не измеримо так - в основном неизменен (т.е. может изменить точность, но не значение).

long - Точный, но имеет предел значений - примитив, поэтому он не может быть побежден для скорости - неизменный - математика проще и понятнее писать.

BigInteger - Возможно, ваш лучший дом на полпути между вышеперечисленными - непреложный, поэтому вы должны делать новые, когда вы меняете стоимость - вы вряд ли достигнете своих пределов.

+2

'long' столь же изменчив, как и BigInteger. –

+0

Мне не нужно беспокоиться о мутабилити, поскольку эти значения не будут работать в многопоточном fasion ... – vach

+0

@MarkoTopolnik - Да - в смысле пуризма - но есть много функциональных отличий между 'long c = b + 1' и' BigInteger c = b.plus (BigInteger.ONE) '. Возможно, изменчивое было неправильным словом - возможно, я имел в виду более «сжатые математики». – OldCurmudgeon

Смежные вопросы