Преобразование числа Java в BigDecimal: лучший способ

Я ищу лучший способ преобразовать число в BigDecimal.

Достаточно ли этого?

Number number;
BigDecimal big = new BigDecimal(number.toString());

Можем ли мы потерять точность при использовании метода toString()?


person Community    schedule 25.04.2013    source источник
comment
ваш код может выдать NumberFormatException - если number является Double, то есть Infinity или NaN docs.oracle.com/javase/1.5.0/docs/api/java/lang/   -  person Ahmed KRAIEM    schedule 25.04.2013
comment
Спасибо за чаевые ! я забыл это проверить   -  person    schedule 25.04.2013


Ответы (3)


Это нормально, помните, что использование конструктора BigDecimal для объявления значения может быть опасным, если оно не имеет типа String. Рассмотрим ниже...

BigDecimal valDouble = new BigDecimal(0.35);
System.out.println(valDouble);

Это не напечатает 0,35, на самом деле это будет...

0.34999999999999997779553950749686919152736663818359375

Я бы сказал, что ваше решение, вероятно, самое безопасное из-за этого.

person david99world    schedule 25.04.2013
comment
Ага, я это заметил. Меня беспокоит метод toString() для Double, мне было интересно, можем ли мы потерять точность с помощью этого метода. - person ; 25.04.2013
comment
Нет, хотя у вас, естественно, будет больше точности, если это будет BigDecimal в первую очередь. Если речь идет о валюте, вы всегда должны делать все BigDecimal. Если бы он был объявлен как BigDecimal перед преобразованием из Double, это было бы лучшим решением, на мой взгляд, и полностью исключило бы Double из уравнения. - person david99world; 25.04.2013

Можем ли мы потерять точность с помощью метода toString()?

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

Чтобы использовать пример 0,35 в ответе david99world, рассмотрите следующий код:

BigDecimal bd1 = new BigDecimal(0.35);

Number n = 0.35;
BigDecimal bd2 = new BigDecimal(n.toString());

System.out.println(bd1);
System.out.println(bd2);

Интуитивно можно предположить, что два экземпляра BigDecimal идентичны, но вывод показывает, что это не так:

0.34999999999999997779553950749686919152736663818359375
0.35

Первая строка — это точное значение двойного числа, поскольку 0,35 не может быть представлено точно. Вторая строка — 0,35, так как для представления уникального значения больше не требуются цифры дробной части. Например. оператор 0.34999999999999997779553950749686919152736663818359375 == 0.35 будет оцениваться как true.

На самом деле это не потеря точности при создании BigDecimal, неопределенность уже присутствует в вашем «исходном» значении. Проблема скорее в том, что дискретные значения, которые можно использовать, например. значение float или double в качестве источника не обязательно будет представлено точным эквивалентом в экземпляре BigDecimal.

person jarnbjo    schedule 25.04.2013
comment
Это действительно хороший момент, но в вашем тривиальном примере результат toString на самом деле предпочтительнее, потому что он предоставляет буквальное число, которое вы ввели в коде, как если бы вы сделали new BigDecimal("0.35"). Есть ли ситуация, когда подход toString действительно будет проблематичным? - person Drew Nutter; 07.01.2021

Лучший способ

BigDecimal.valueOf(myDouble);

Это то же самое внутри, но это перегруженная функция, которая работает также для longs и оптимизирована для часто используемого значения longs. Так что это более стандартно, просто и легко запоминается.

Источник

person Marco Sulla    schedule 24.07.2019
comment
и он не перегружен для java.lang.Number - person Phu Ngo; 03.12.2019