大浮球在Java打印/双号持续不正确。 这种行为是由于显著位数?(Large float and

2019-10-29 19:05发布

在应用程序中,我的工作的一些数字让转换和长(18位)保存到浮动/双。 这些数字就像参考/身份证的,但不能用于计算。 最近我注意到,在数据有一些出入被存储为浮点/双精度。 我想了解,如果行为是由于什么浮点数调用显著数字,也许是因为同样的一个简单的解释。

我基于以下程序的问题是

  1. 输出NO:5显示了一个非常大的数字(小数点前39位)作为浮动的最大值。 那么,为什么浮动不能显示上述7位准确任何东西。 正是由于IS只支持6-7显著数字。
  2. 输出NO:10显示了一个非常大的数量的双最大值。 为什么然后双击无法显示上述16位准确东西。 正是由于IS只支持15位显著。
  3. 什么是显著数字的真正含义? 这是否意味着任何数字后,这个数字将无法准确不论谈到之前或之后小数点代表?

注:我对这个课题的研究之后,我现在明白了,浮点数是由它们的性质不准确,不应该被用来表示需要精确表述的东西。 不过我觉得有点困惑上述行为和显著数字。

public class Main
{
    public static void main(String[] args) {
        System.out.printf( "1. Float value of 50000000115 is : %,f. Expected output was 50000000115.000000 \n", 50000000115f );
        System.out.printf( "2. Float value of 50000000116 is : %,f. Expected output was 50000000116.000000 \n", 50000000116f );
        System.out.printf( "3. Float value of 50000000117 is : %,f. Expected output was 50000000117.000000 \n\n", 50000000117f );

        System.out.printf( "4. Float value of 2175863596593954381 is : %,f. Expected output was 2175863596593954381.000000 \n\n", 2175863596593954381f );

        System.out.printf( "5. Float.MAX_VALUE: %,f\n\n", Float.MAX_VALUE );

        System.out.printf( "6. Double value of 50000000115 is : %,f\n", 50000000115d );
        System.out.printf( "7. Double value of 50000000116 is : %,f\n", 50000000116d );
        System.out.printf( "8. Double value of 50000000117 is : %,f\n\n", 50000000117d );

        System.out.printf( "9. Double value of 2175863596593954381 is : %,f. Expected output was  2175863596593954381.000000 \n\n", 2175863596593954381d );

        System.out.printf( "10. Double.MAX_VALUE: %,f\n\n", Double.MAX_VALUE );

        System.out.printf( "11. Float value of number gives expected result till 7 digits ie 12345678 is : %,f\n", 12345678f );
        System.out.printf( "12. Float value of number gives expected result till 7 digits ie 11111111 is : %,f\n", 11111111f );
        System.out.printf( "13. Double value of number gives expected result till 16 digits ie 1122334455667788 is : %,f\n", 1122334455667788d );
        System.out.printf( "14. Double value of number gives expected result till 16 digits ie 1111222233334444 is : %,f\n", 1111222233334444d );
    }
}

上述程序的输出

  1. 的浮动50000000115值为:49,999,998,976.000000。 预计产量为50000000115.000000
  2. 的浮动50000000116值为:49,999,998,976.000000。 预计产量为50000000116.000000
  3. 的浮动50000000117值为:49,999,998,976.000000。 预计产量为50000000117.000000

  4. 的浮动2175863596593954381值为:2,175,863,554,941,386,750.000000。 预计产量为000 2175863596593954381.000

  5. Float.MAX_VALUE:340,282,346,638,528,860,000,000,000,000,000,000,000.000000

  6. 的50000000115双重价值:50,000,000,115.000000

  7. 的50000000116双重价值:50,000,000,116.000000
  8. 的50000000117双重价值:50,000,000,117.000000

  9. 的2175863596593954381双重价值:2,175,863,596,593,954,300.000000。 预计产量为00000 2175863596593954381.0

  10. Double.MAX_VALUE:179,769,313,486,231,570,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,00 0,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,00 0,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,00 0,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000.000000

  11. 一些浮点值给出了预期的结果,直到7位,即12345678是:12,345,678.000000

  12. 一些浮点值给出了预期的结果,直到7位,即11111111是:11,111,111.000000
  13. 一些双值给出了预期的结果,直到16个数字,即1122334455667788是:1,122,334,455,667,788.000000
  14. 一些双值给出了预期的结果,直到16个数字,即1111222233334444是:1,111,222,233,334,444.000000

Answer 1:

Java的Float型(IEEE-754 binary32)实际上有两个组成部分:

  • 为单位的整数,从-16,777,215到16777215(2 24 -1)和
  • 即2 2 104 2 -149的功率的单元。

,保持的范围内的单元的数量的最小单位(范围内)被使用。

例如,对于50000000115,所以不能使用2048(2 12)的单位大小,因为50000000115约为24414062单元2048,其是超过16,777,215单位。 因此,我们使用4096的单元尺寸。

50000000115正是12,207,031.278076171875单位的4096,但是我们只能使用单位的整数倍,所以Float最接近的值到50000000115是12207031个单位的4096,这是49999998976。

在你的问题其他值也同样表示,但Java的用于格式化数字规则%,f结果的小数位数数量有限被用来显示值。 所以,在你的一些例子,我们看到尾随零,其中内部编号的实际数学值是不同的。

对于Double (IEEE-754 binary64),这两个组成部分是:

  • 为单位的整数,从-9,007,199,254,740,991到+9,007,199,254,740,991(2 53 -1)和
  • 即2 2 972 2 -1074的功率的单元。


文章来源: Large float and double numbers in java printing/persisting incorrectly. Is this behavior due to number of significant digits?