Java中的大浮点数和双精度数会错误地打印/保留.这是由于有效位数引起的吗? [英] Large float and double numbers in java printing/persisting incorrectly. Is this behavior due to number of significant digits?

查看:114
本文介绍了Java中的大浮点数和双精度数会错误地打印/保留.这是由于有效位数引起的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在使用的应用程序中,一些数字被转换并从long(18位数字)保存为float/double.这些数字类似于参考/编号,但不用于计算.最近,我注意到以浮点数/双精度数存储的数据存在一些差异.我试图了解是否该行为是由于什么浮点数称为有效数字,并且可能是对此的简单解释.

In an application I am working some numbers get converted and saved from long(18 digits) to float/double. These numbers are like Reference/Id's but not used for calculations. Recently I noticed some discrepancies in data being stored as float/double. I am trying to understand if the behavior is due to what floating point numbers call significant digits and maybe a simple explanation for the same.

基于以下程序,我的问题是

My questions based on below program are

  1. 输出编号:5显示一个很大的数字(十进制前39位)作为float的最大值.为什么然后float无法准确显示7位数以上的数字.这是因为仅支持6-7个有效数字.
  2. 输出编号:10显示一个很大的数字,为double的最大值.为什么双精度不能正确显示16位以上的数字.因为仅支持15个有效数字.
  3. 有效数字到底是什么意思?这是否意味着无论该数字位于小数点之前还是之后,该数字之后的任何数字都将无法准确显示?

注意:经过对这一主题的研究之后,我现在知道,浮点数本质上是不准确的,因此不应用于表示需要精确表示的事物.我仍然对上述行为和有效数字感到困惑.

NOTE : After my research on this topic , I do now understand that floating point numbers are by their nature inaccurate and should not be used to represent things that require accurate representations. Still I feel a bit confused about the above behavior and significant digits.

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

  1. Float value of 50000000115 is : 49,999,998,976.000000. Expected output was 50000000115.000000
  2. Float value of 50000000116 is : 49,999,998,976.000000. Expected output was 50000000116.000000
  3. Float value of 50000000117 is : 49,999,998,976.000000. Expected output was 50000000117.000000

2175863596593954381的浮点值为:2,175,863,554,941,386,750.000000.预期产量为2175863596593954381.000 000

Float value of 2175863596593954381 is : 2,175,863,554,941,386,750.000000. Expected output was 2175863596593954381.000 000

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

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

50000000115的双精度值是:50,000,000,115.000000

Double value of 50000000115 is : 50,000,000,115.000000

50000000117的双精度值是:50,000,000,117.000000

Double value of 50000000117 is : 50,000,000,117.000000

2175863596593954381的双精度值是:2,175,863,596,593,954,300.000000.预期产量为2175863596593954381.0 00000

Double value of 2175863596593954381 is : 2,175,863,596,593,954,300.000000. Expected output was 2175863596593954381.0 00000

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,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,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,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.000000

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

数字的浮点值给出预期的结果,直到7位数字,即12345678为:12,345,678.000000

Float value of number gives expected result till 7 digits ie 12345678 is : 12,345,678.000000

推荐答案

Java的Float类型(IEEE-754 binary32)实际上具有两个组件:

Java’s Float type (IEEE-754 binary32) effectively has two components:

  • 从−16,777,215到+16,777,215的整数单位(2 24 -1)和
  • 一个从2 104 到2 −149 的2的幂的单位.
  • a integer number of units from −16,777,215 to +16,777,215 (224−1) and
  • a unit that is a power of two from 2104 to 2−149.

使用将单位数量保持在范围内的最小单位(范围内).

The smallest unit (within range) that keeps the number of units within range is used.

例如,对于50,000,000,115,我们不能使用2048(2 12 )的单位大小,因为50,000,000,115大约是2048的24,414,062单位,大于16,777,215单位.因此,我们使用的单位大小为4096.

For example, with 50,000,000,115, we cannot use a unit size of 2048 (212), because 50,000,000,115 is about 24,414,062 units of 2048, which is more than 16,777,215 units. So we use a unit size of 4096.

50,000,000,115恰好是4096的12,207,031.278076171875单位,但是我们只能使用整数的单位,因此最接近50,000,000,115的Float值是4096的12,207,031单位,即49,999,998,976.

50,000,000,115 is exactly 12,207,031.278076171875 units of 4096, but we can only use an integer number of units, so the Float value closest to 50,000,000,115 is 12,207,031 units of 4096, which is 49,999,998,976.

问题中的其他值也以类似的方式表示,但是Java用%,f格式化数字的规则导致使用有限数量的十进制数字来显示该值.因此,在您的某些示例中,我们看到内部数字的实际数学值不同的尾随零.

The other values in your question are represented similarly, but Java’s rules for formatting numbers with %,f result in limited numbers of decimal digits being used to show the value. So, in some of your examples, we see trailing zeros where the actual mathematical value of the internal number is different.

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

For Double (IEEE-754 binary64), the two components are:

  • 从-9,007,199,254,740,991到+9,007,199,254,740,991的整数单位(2 53 -1)和
  • 一个从2 972 到2 −1074 的2的幂的单位.
  • a integer number of units from −9,007,199,254,740,991 to +9,007,199,254,740,991 (253−1) and
  • a unit that is a power of two from 2972 to 2−1074.

这篇关于Java中的大浮点数和双精度数会错误地打印/保留.这是由于有效位数引起的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆