Ответ 1
Для большинства входных значений оба метода должны давать одинаковые значения. Хотя все еще возможно, что они не могут, это не кажется вероятным.
BigDecimal(String)
конструктор Javadocs утверждает:
API Note:
Для значений, отличных от
float
иdouble
NaN и ± Infinity, этот конструктор совместим со значениями, возвращаемымиFloat.toString(float)
иDouble.toString(double)
.
Однако метод Double.parseDouble(String)
гласит:
Возвращает новый
double
, инициализированный значением, представленным указаннымString
, как выполняется методомvalueOf
классаDouble
.
И это продолжает описывать формат, принятый методом.
Пусть это проверят!
Давайте проверим некоторые значения. Выглядит как невероятно громадное усилие, чтобы проверить это исчерпывающе, но пусть проверка включает некоторые строковые значения, которые представляют значения, о которых известно, что они вызывают ошибки с плавающей запятой или являются неточными представлениями.
public static void main(String[] args)
{
String[] values = {"0", "0.1", "0.33333333333333333333", "-0", "-3.14159265", "10.1e100",
"0.00000000000000000000000000000000000000000000000000142857142857",
"10000000000.000000000000000001", "2.718281828459",
"-1.23456789e-123", "9.87654321e+71", "66666666.66666667",
"1.7976931348623157E308", "2.2250738585072014E-308", "4.9E-324",
"3.4028234663852886E38", "1.1754943508222875E-38", "1.401298464324817E-45",
String.valueOf(Math.E), String.valueOf(Math.PI), String.valueOf(Math.sqrt(2))
};
for (String value : values) {
System.out.println(isDoubleEqual(value));
}
}
// Test if the representations yield the same exact double value.
public static boolean isDoubleEqual(String s) {
double d1 = Double.parseDouble(s);
double d2 = new BigDecimal(s).doubleValue();
return d1 == d2;
}
За эти значения я получаю все true
с. Это ни в коем случае не является исчерпывающим, поэтому было бы очень трудно доказать, что это верно для всех возможных значений double
. Все, что нужно, это один false
, чтобы показать контрпример. Однако это, кажется, является некоторым доказательством того, что это верно для всех допустимых строковых представлений double
.
Я также пробовал ведущие пробелы, например " 4"
. Конструктор BigDecimal(String)
выбросил NumberFormatException
, но Double.parseDouble
правильно обрезал ввод.
Конструктор BigDecimal(String)
не будет принимать Infinity
или NaN
, но вы спрашивали только о нормальном конечном диапазоне. Метод Double.parseDouble
принимает шестнадцатеричные представления с плавающей запятой, но BigDecimal(String)
- нет.
Если вы включите эти крайние случаи, один метод может вызвать исключение, а другой - нет. Если вы ищете обычные строки из 10 с конечными значениями в пределах диапазона, ответ "кажется вероятным".