Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 格式不打印所有双位数,即使精度超过可用位数_Java_Double_Precision_Number Formatting_Bigdecimal - Fatal编程技术网

Java 格式不打印所有双位数,即使精度超过可用位数

Java 格式不打印所有双位数,即使精度超过可用位数,java,double,precision,number-formatting,bigdecimal,Java,Double,Precision,Number Formatting,Bigdecimal,我不能对这件事耿耿于怀 看起来JDK的数字格式化例程即使在给定足够精度的字段时也无法打印两位数 特别是,我不明白为什么下面程序的第二个输出行是: b、 doubleValue=>34981.29000000000000000000000000000000000000000000000000 我认为打印的值应该是34981.2900000000008731149137020111083984375000000000000 你能帮我理解为什么会发生这种情况吗: PrecisionLoser.java

我不能对这件事耿耿于怀

看起来JDK的数字格式化例程即使在给定足够精度的字段时也无法打印两位数

特别是,我不明白为什么下面程序的第二个输出行是:

b、 doubleValue=>34981.29000000000000000000000000000000000000000000000000

我认为打印的值应该是34981.2900000000008731149137020111083984375000000000000

你能帮我理解为什么会发生这种情况吗:

PrecisionLoser.java 输出
通过调试器查看转换过程,我认为首先会将double转换为字符串,忽略精度。然后,调整字符串以匹配指定的精度,并在末尾用0填充,或用舍入截断-请参阅sun.misc.FormattedFloatingDecimal的applyPrecision


而且,原始转换似乎使用最小的?如果重新分析,将产生原始双精度值的十进制数字数。

谢谢您的解答。您知道如何打印真实数字吗?转换为BigDecimal?:更严重的是,我不清楚你为什么要这么做?在双精度的上下文中,34981.29和34981.2900000000008731149137020111083984375是完全相同数字的十进制表示形式。生成原始值的最小十进制数字数称为往返格式。有些语言可以做到这一点,包括Java。
import java.math.BigDecimal;

public class PrecisionLoser {
    public static void main(final String[] args) {
        final BigDecimal b = new BigDecimal("34981.29");
        System.out.printf("b                => %.50f%n", b);
        System.out.printf("b.doubleValue()  => %.50f%n", b.doubleValue());
        System.out.printf("b.floatValue()   => %.50f%n", b.floatValue());
        System.out.printf("Double.MIN_VALUE =>     %.50f%n", Double.MIN_VALUE);
        System.out.println("-");
        final double d = 34981.2900000000008731149137020111083984375;
        System.out.printf("d                               => %.50f%n", d);
        System.out.printf("new BigDecimal(d)               => %.50f%n", new BigDecimal(d));
        System.out.printf("new BigDecimal(b.doubleValue()) => %.50f%n", new BigDecimal(b.doubleValue()));
        System.out.printf("d == b.doubleValue()            => %b%n", d == b.doubleValue());
        final double e = 34981.29;
        System.out.printf("d == e                          => %b%n", d == e);
        System.out.println("-");
        System.out.printf("Double.doubleToLongBits(b.doubleValue()) => 0x%16x%n", Double.doubleToLongBits(b.doubleValue()));
        System.out.printf("Double.doubleToLongBits(d)               => 0x%16x%n", Double.doubleToLongBits(d));
        System.out.printf("Double.doubleToLongBits(e)               => 0x%16x%n", Double.doubleToLongBits(e));
    }
}
$ javac PrecisionLoser.java
$ java PrecisionLoser
b                => 34981.29000000000000000000000000000000000000000000000000
b.doubleValue()  => 34981.29000000000000000000000000000000000000000000000000
b.floatValue()   => 34981.28906250000000000000000000000000000000000000000000
Double.MIN_VALUE =>     0.00000000000000000000000000000000000000000000000000
-
d                               => 34981.29000000000000000000000000000000000000000000000000
new BigDecimal(d)               => 34981.29000000000087311491370201110839843750000000000000
new BigDecimal(b.doubleValue()) => 34981.29000000000087311491370201110839843750000000000000
d == b.doubleValue()            => true
d == e                          => true
-
Double.doubleToLongBits(b.doubleValue()) => 0x40e114a947ae147b
Double.doubleToLongBits(d)               => 0x40e114a947ae147b
Double.doubleToLongBits(e)               => 0x40e114a947ae147b