Lightweight Java Decimal класса

голоса
12

Я рассматриваю написание двух ограниченных точности альтернатив BigDecimal, а именно DecimalInt и DecimalLong. Они были бы способны справиться с числами в пределах реальных границ Int и долго с произвольным числом знаков после запятой, creatable в обеих изменяемых и неизменяемых формах. Мой план, чтобы сделать поддержку DecimalInt +/- 999,999,999 до +/- 0.999999999 и DecimalLong то же самое, но с до 18 цифр.

Это будет сделано путем поддержания десятичной цифры значение счетчика 0-9 для DecimalInt и 0-18 для DecimalLong вдоль стороны фактического значения, хранящегося в качестве масштабируемого междунар или долго. Нормальное использование было бы для небольшого числа десятичных знаков, таких как для денежных и фондовых цен, обычно 2-4 знаков после запятой.

Существенные требования (а) постный след (2 классов, плюс OverflowException), и (б) полная поддержка всех основных операций плюс все Math что имеет смысл.

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

Мои вопросы: Имеет это уже сделано? Есть ли скрытые тонкости в этом, поэтому он еще не был сделан? Кто-нибудь слышал слухи о Java с поддержкой десятичного типа, как DotNet-х.

EDIT: Это отличается от BigDecimal, потому что она должна быть (а) чертовски много более эффективной, чтобы не иметь дело с массивом целых чисел, и (б) он не будет обернуть BigInteger так будет компактнее на память тоже, и (с) он будет иметь изменяемый вариант так будет быстрее там. В итоге - меньше накладные расходов для простых случаев применения, как «Я хочу, чтобы сохранить баланс банка без накладных расходов BigDecimal и неточности двойного».

EDIT: Я намерен делать всю математику с помощью Int или долго, чтобы избежать классической проблемы: 1586.60-708.75 = 877.8499999999999 вместо 877,85

Задан 09/12/2008 в 21:05
источник пользователем
На других языках...                            


5 ответов

голоса
12

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

Чтобы использовать пример: для любого финансового применения, сэкономив несколько десятков байт не является проблемой, и ограниченная точность прерыватель сделки (цены на акции Мои содержат обычно 2-4 цифры в США, но если вы хотите иметь дело с развивающимися рынками , вы будете сталкиваться с валютами с безудержной инфляцией, где 15-значный сумма а покупает вам половину буханки хлеба).

В основном, это звучит как просто еще один случай преждевременной оптимизации.

Ответил 11/12/2008 в 11:39
источник пользователем

голоса
1

Большинство людей, которые особенно обеспокоены ошибок округления использовать BigDecimal и BigInteger, который выполняет достаточно хорошо в большинстве ситуаций.

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

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

System.out.printf("%.2f%n", 1586.60-708.75);

печать

877.85
Ответил 24/11/2010 в 00:03
источник пользователем

голоса
0

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

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

Ответил 10/12/2008 в 15:38
источник пользователем

голоса
0

Если ваш фокус для портативных устройств смотрите на Real . Real позволяет точность числа , чтобы быть установлено от 0 до 16. Он предназначен для сотовых телефонов MIDP.

Также интерес, посмотрите на конструктивный вещественных чисел библиотеки. Это не легкое , хотя.

Ссылаясь на комментарий ниже, вы можете не использовать Apache Commons Math Library работать с дробями? Есть ли какая - то причина , что не будет работать?

Ответил 09/12/2008 в 21:31
источник пользователем

голоса
-1

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

Необходимо указать, что наименьшее значение (не ноль), нужно представить это. Это будет 10 ^ - (2 ^ п), где п + 1 это число бит, которые вы распределили экспонент. С BigDecimal это 10 ^ - (2 ^ 31). Можно использовать произвольный размер показатель, но этот диапазон должен быть достаточно для всех.

Так что вам нужно неограниченное число мантисса, чтобы дать вам произвольную точность, а показатель фиксированного размера, в зависимости от того, что вы хотите, чтобы ваше минимальное представимо значение будет. По существу, это BigDecimal; единственное изменение вы будете использовать какой-то меньший объект, а не междунар используется BigDecimal. Я сомневаюсь в том, что экономия пространства стоит. Я думаю, что BigDecimal собирается делать то, что вам нужно с едва больше использования памяти, чем любое решение, которое вы ремесленными себя.

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

Ответил 09/12/2008 в 23:43
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more