有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java语言计算不准确?

我尝试了以下for循环:

for(double i = 0.0; i<=0.001; i+=0.0001)
    System.out.println(i);

我得到以下输出:

0.0
1.0E-4
2.0E-4
3.0000000000000003E-4
4.0E-4
5.0E-4
6.000000000000001E-4
7.000000000000001E-4
8.000000000000001E-4
9.000000000000002E-4

我的问题是:

  • 这些额外的.000000000000001是怎么来的
  • 这些额外的数字会一直出现吗?或者我的代码中有问题吗
  • 这些错误是否只出现在Java语言中,或者其他编程语言中
  • double是否适合于for循环

共 (2) 个答案

  1. # 1 楼答案

    遗憾的是,并非所有数字都能在floating point中准确表示:

    For example, the decimal number 0.1 is not representable in binary floating-point of any finite precision; the exact binary representation would have a "1100" sequence continuing endlessly:

    e = −4; s = 1100110011001100110011001100110011..., where, as previously, s is the significand and e is the exponent.

    When rounded to 24 bits this becomes

    e = −4; s = 110011001100110011001101, which is actually 0.100000001490116119384765625 in decimal.

  2. # 2 楼答案

    尝试使用BigDecimal,下面是我的示例代码:

    import java.math.BigDecimal;
    
    public class Test {
    
        private static final BigDecimal UPPER_LIMIT = new BigDecimal(0.001);
        private static final BigDecimal STEPS = new BigDecimal(0.0001);
    
        public static void main(String[] args) {
            for(BigDecimal i = BigDecimal.ZERO; i.compareTo(UPPER_LIMIT) != 1; i = i.add(STEPS)){
                System.out.printf("%.4f\n", i);
            }
    
        }
    
    }
    

    输出为:

    0.0000
    0.0001
    0.0002
    0.0003
    0.0004
    0.0005
    0.0006
    0.0007
    0.0008
    0.0009
    

    顺便说一句,我并没有把时间花在内存管理和其他细节上,这应该是一个比使用原语更繁重的过程