2013-03-07 135 views
2

我正在运行此代码,循环似乎没有停止在指定的条件下。即使条件满足后,for循环仍然继续执行

for(double i=1.0; i!=2.0; i+=0.2){ 
    System.out.println("The value of i :" +i); 
} 

这是双数在Java中表示方式的问题吗?

+1

'这是双数字在Java中表示方式的问题吗?'确切地说,浮点数的二进制表示是原因。这是你应该聪明地解决的问题:'for(double i = 1.0; i <= 2.0; i + = 0.2){'尽管[我的答案在这里](http://stackoverflow.com/a/13513206/1667004 )是C,对于Java也是一样的馅饼...... – ppeterka 2013-03-07 14:17:44

回答

7

这是一个相当普遍的问题:0.2不能在一个double精确表示,所以2.0不等于10 0.2的相加之和。您需要使用<而不是!=来停止循环。

请注意,你的循环会为增量等于2的负电源,工作说,0.25:下面的循环工作正常,并停止按预期:

for(double i=1.0; i!=2.0; i+=0.25){ 
    System.out.println("The value of i :" +i); 
} 

这工作,因为0.25可以完全代表double。这个小实验表明,在比较double的平等或不平等时,你需要非常谨慎。

+0

实际上2之前的最后一个值大约是1.999。 。 。下一个值是2.1999。 。 。所以它永远不会是2.0。 最好避免使用浮点数进行比较?像dasblinkenlight说的 – 2013-03-07 14:21:09

+1

,用< or >代替直接比较。对于循环来说,这通常是一个好主意 – 2013-03-07 14:22:07

+0

@JeffHawthorne我不一定会把它推广到基于整数的条件循环:赞成使用'!='的论据是这样一个循环的后置条件更强,使您的程序更容易正式分析。 – dasblinkenlight 2013-03-07 14:24:31

2

是的就是这样 - 0.2不能完全表示为双。要看到确切值,你可以运行下面的程序:

public static void main(String[] args) { 
    for (double i = 1.0; i != 2.0 && i < 3.0; i += 0.2) { 
     System.out.println("The value of i :" + new BigDecimal(i)); 
    } 
} 

它打印:

The value of i :1 
The value of i :1.1999999999999999555910790149937383830547332763671875 
The value of i :1.399999999999999911182158029987476766109466552734375 
The value of i :1.5999999999999998667732370449812151491641998291015625 
The value of i :1.79999999999999982236431605997495353221893310546875 
The value of i :1.9999999999999997779553950749686919152736663818359375 
The value of i :2.199999999999999733546474089962430298328399658203125 
The value of i :2.399999999999999911182158029987476766109466552734375 
The value of i :2.600000000000000088817841970012523233890533447265625 
The value of i :2.800000000000000266453525910037569701671600341796875 

您的选择:

  • 轮数
  • 使用i < 2.0条件(但你可能会错过一次迭代取决于舍入)
  • 使用a BigDecimal 0.2的精确表示
+1

+ +1注意不要让我的Eclipse崩溃,当我尝试它:) – cowls 2013-03-07 14:20:13

相关问题