Комментарии 42
Причем по уровню исполнения, эта библиотека написана в лучшем случае мидлом.
А какие косяки в исполнении вы видите?
И самое главное — плохое API (можете сказать что делают product и quotient не глядя в исходники?) и мутабельность. От мутабельности уходят не просто так, а потому что это error-prone подход.
Мне очень жаль, что вас огорчило нарушение Open-closed principle в библиотеке из 2 классов без планов расширения.
Ваши замечания насчёт getScale и ArithmeticException противоречат требованиям, из-за которых проект был создан. У меня сложилось впечатление, что вы эти требования не понимаете.
Желаю вам и дальше пребывать в уверенности, что все Java программы должны писаться по одному шаблону и для похожих целей. А все что не укладывается в привычные рамки — трэш и говнокод.
Вашу оценку моей квалификации оставлю без комментариев.
А почему бы не считать все в копейках? Или есть проблемы у такого решения?
Интересная вещь. Для себя решил остаться на BigDecimal в виду неудачного гугляжа альтернатив в свое время. Использую там, где точность до 12 знаков (крипта), радует в нем то, что можно и более высокую точность использовать.
Конечно,
В целом, умножение получается в 4 раза быстрее BigDecimal, деление — в 1.5
Тоже прирост. В другой стороны в BD много фишек по округлению в любую сторону, что очень удобно, когда нужно не всегда классческое округление.
Вы уверены, что ваша библиотека корректно будет работать во всех случаях умножения (и в каким именно случаях)?
У вас же можно умножать только числа с порядком не больше половины максимального, да ещё и с учётом множителя дробной части.
Т.е. 1'000'000'000.0000*1'000'000'000.0000 приведёт к катастрофе. И, что хуже, при таком подходе к перемножению чисел разной точности будут неочевидные побочные эффекты. Например, 10'000'000'000.0000*10.000000 (второе число с большим числом знаков после запятой) тоже приведёт к катастрофе. Вы можете тупо единицу на единицу при большом количество занком после запятой умножить и получить неконтролируемое переполнение. По-моему, так делать нельзя. Нужно, как минимум, ловить потенциальные перполнения по точности и значению аргументов и обрабатывать пограничные случаи отдельно.
А ещё есть, как минимум, операцииквадратного корня и возведения в степень, которые даже в бухгалтерии используются — они у вас при таком подходе вообще неправильно вычисляться будут.
И про опитимизацию деления и взятия остатка — вы точно в этом уверены (что будет сгенерирована одна операция деления)?
умножать только числа с порядком не больше половины максимального
Нет, умножать/делить/etc можно любые числа при условии что результат вместе с дробной частью влезает в long. Если не влезает, возвращается NaN, который легко проверить. Напомню, Java в случае переполнения типа Long.MAX_VALUE * 10 вообще возвращает мусор.
Ваш первый пример — переполнение (18 нулей до запятой и 4 после):
System.out.println(new Decimal4().parse("1000000000.0000")
.mulRD(new Decimal4().parse("1000000000.0000"))); // "NaN"
Ваш второй пример работает нормально:
System.out.println(new Decimal4().parse("10000000000.0000")
.mulRD(new Decimal6().parse("10.000000"))); // 100000000000.0000
Насчет "вы уверены?". 100% гарантию отсутствия багов я дать не могу, как и большиство разработчиков. Но класс достаточно хорошо оттестирован, в том числе и на граничных случаях. Если вы нашли конкретную проблему, нет ничего проще написать падающий юнит-тест и прислать мне, я буду очень признателен. У библиотеки нет зависимостей, можно просто скопировать 2 класса из Гитхаба в любой пакет.
Я категорически не приветствую написание велосипедов, но моя исходная задача не решалась стандартными средствами, поэтому пришлось писать по-своему.
Утверждение "любые велосипеды содержат больше багов чем любые не-велосипеды" некорректно.
Под уверенностью я имел в виду умножение отрицательных чисел с переполнением — там NaN правильно обрабатывается?
0.1 * 0.1 * 0.1 = 0.30000000000000004
в JavaОдин маленький падающий юнит-тест, вместо долгих рассуждений на тему «это не заработает»
Далеко не сразу нашёл лицензию проекта — она указана только в паре файлов. Стоит её добавить в readme и корень проекта (чтобы github её в заголовке указывал), pom.xml и во все исходники.
Вам стоило сделать стресс-тест со случайными числами и сверять результат с классом BigDecimal. Или же взять юнит-тесты со свободных либ на других языках, коли уж вы связаны с финансами. Тогда всем «критикам» можно было бы легко парировать.
и есть процессоры, например IBM Power, которые поддерживают арифметику с десятичной запятой. Процессоры intel тоже поддерживают, но не уверен что она используется в Java. Думаю, всё это не учитывается в вашей библиотеке.
Быстрая математика с фиксированной точкой для финансовых приложений на Java