Почему конструкция Bigdecimal (double d) все еще существует? - PullRequest
14 голосов
/ 29 июня 2009

Я заметил существенную боль над этим конструктором (даже здесь, в Переполнении стека). Люди используют его, хотя в документации четко указано:

Результаты этого конструктора могут быть несколько непредсказуемыми http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)

Я даже видел, что JSR-13 УТВЕРЖДЕН с рекомендацией:

Существующие спецификации, которые могут быть устаревшими: мы предлагаем отказаться от конструктора BigDecimal (double), который в настоящее время дает результаты, отличные от метода Double.toString ().

Несмотря на все это, конструктор еще не устарел.

Мне бы очень хотелось услышать любые мнения по этому поводу.

Ответы [ 3 ]

20 голосов
/ 29 июня 2009

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

Я не совсем согласен с формулировкой документации в конструкторе BigDecimal(double):

Результаты этого конструктора могут быть несколько непредсказуемый . Можно Предположим, что запись new BigDecimal(0.1) в Java создает BigDecimal что точно равно 0.1 (немасштабированное значение 1 со шкалой 1), но на самом деле оно равно в 0.1000000000000000055511151231257827021181583404541015625.

(выделение добавлено.)

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

Если учесть, что значения с плавающей запятой не могут точно представить все десятичные значения, значение, возвращаемое с помощью BigDecimal(0.1), равное 0.1000000000000000055511151231257827021181583404541015625, действительно имеет смысл.

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

Мое предположение о том, почему конструктор BigDecimal(double) не считается устаревшим, заключается в том, что поведение можно считать правильным, и, пока известно, как работают представления с плавающей запятой, поведение конструктора не слишком удивительно.

2 голосов
/ 29 июня 2009

Амортизация устарела. Части API помечены как устаревшие только в исключительных случаях.

Итак, запустите FindBugs как часть вашего процесса сборки. FindBugs имеет подключаемый API-интерфейс детектора, а также с открытым кодом (LGPL, IIRC).

1 голос
/ 29 июня 2009

Этот конкретный конструктор, как и все операции с плавающей запятой, является приближенным. На самом деле он не сломан, у него просто есть недостатки.
Просто сделайте свое исследование, подойдите к нему с осторожностью, и вы не получите никаких сюрпризов. При назначении десятичных литералов для double / float вы сталкиваетесь точно так же.

...