Как отобразить дополнительные цифры числа с плавающей запятой? - PullRequest
1 голос
/ 07 февраля 2012

У меня есть Double , который я создал так:

Double d = Double.parseDouble( "27.86753" ); // All the digits of this double value are 27.867530822753906

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

Ответы [ 3 ]

5 голосов
/ 07 февраля 2012

О, чувак, интересно.Вы хотите точно узнать, как double делает это неточно.

Я думаю, new BigDecimal(double).toString() выдаст вам все неправильные цифры, поскольку BigDecimal представляет число с точно заданным значением.точность.

РЕДАКТИРОВАТЬ: Ohhhhhhhh, я думаю, что я вижу, что происходит.

Позвольте мне попытаться объяснить это так: Double.toString возвращает наименее точный String такой, что Double.parseDoubleвернет точно такое же double - , что будет достаточно цифр, чтобы «однозначно идентифицировать» точное значение IEEE 754, хотя фактическое значение может иметь больше цифр, чем напечатано.То, что Double.toString не дает вам столько цифр, сколько вы ожидаете, не означает, что значение фактического IEEE 754 с двойной точностью округляется до такого количества цифр.new BigDecimal(double).toString вернет точное сохраненное значение IEEE-754.

ОБНОВЛЕНИЕ:

Что происходит, когда он печатает 27.86753, это на самом деле больше точное значение, чем цифры, которые вы указали в качестве правильного ответа, 27.867530822753906.Это потому, что toString предназначен для распечатки столько, сколько необходимо, чтобы Double.parseDouble(Double.toString(value)) не использовался.

Я запустил следующий код:

public static void main(String[] args) {
  double dWithFloat = Double.parseDouble(Double.toString(Float.parseFloat("27.86753")));
  double dJustParsed = Double.parseDouble("27.86753");
  System.out.println(dWithFloat);
  System.out.println(dJustParsed);

  BigDecimal bigFromFloat = new BigDecimal(dWithFloat);
  BigDecimal bigJustParsed = new BigDecimal(dJustParsed);
  System.out.println(bigFromFloat); 
    // prints the exact value from the double,
    // doesn't round or truncate like Double.toString
  System.out.println(bigJustParsed);

}

и распечатано

27.867530822753906 // Double.toString(Double.parseDouble(Double.toString(Float.parseFloat("27.86753"))));
27.86753 // Double.toString(Double.parseDouble("27.86753")) is indeed a no-op
27.86753082275390625 // This is the _actual_ value from D.parseD(D.toString(F.parseF("27.86753")))
27.867529999999998580051396857015788555145263671875 // This is the actual value from D.parseD("27.86753")

И действительно, это второе значение заметно ближе к 27,86753, с запасом примерно в 0,0000008.

1 голос
/ 07 февраля 2012

Возможно, вы захотите использовать java.math.BigDecimal, если у вас есть явные способы управления масштабированием и правилами округления.Вы не можете сделать это с Double.

0 голосов
/ 07 февраля 2012

Ужасно, но работает:

Double d = Double.parseDouble( Double.toString( Float.parseFloat( "27.86753" ) ) ); // Sets the value of the Double to 27.867530822753906
...