最小化数值误差

下面有一段程序是计算从0.01到1.0的和;

package testsum;

public class TestSum {
           public static void main(String [] args)
           {
        	   float sum = 0;
        	   for(float i = 0.01f;i <= 1.0f; i = i+0.01f){
        		   sum  += i;
        	   }
        	   System.out.println("The sum is " + sum);
           }
}

输出结果为:The sun is 50.499985

事实上其输出的正确结果为50.50,但是答案却不是的,之所以会出现这种现象是因为浮点数在计算机中有固定的位数来表示,所以就不能精确的表示某些浮点数。如果将程序中的float改为double应该可以看到一些改善,因为float变量占32位,double占64位。

package testsum;

public class TestSum {
           public static void main(String [] args)
           {
        	   double sum = 0;
        	   for(double i = 0.01;i <= 1.0; i = i+0.01){
        		   sum  += i;
        	   }
        	   System.out.println("The sum is " + sum);
           }
}

实际输出的结果为:49.50000000000003。如果将每次的i都打印出来我们可以看到最后一个i的数值比1大,并不是精确的1。所以最后一个数并没有加上。为了解决这个问题我们可以试用计数器进行计算确保每一个数都被加进来。

package testsum;

public class TestSum {
           public static void main(String [] args)
           {
        	   double sum = 0;
        	   double current = 0.01;
        	   for(int i = 1;i < 100; i++){
        		   sum  += current;
        		   current += 0.01;
        	   }
        	   System.out.println("The sum is " + sum);
           }
}

输出的结果为:49.50000000000003。这是从小到大添加数字。

package testsum;

public class TestSum {
           public static void main(String [] args)
           {
        	   double sum = 0;
        	   double current = 1.0;
        	   for(int i = 1;i < 100; i++){
        		   sum  += current;
        		   current -= 0.01;
        	   }
        	   System.out.println("The sum is " + sum);
           }
}

输出结果为:50.48999999999995。这是从大到小添加数字两次输出的结果却不一样。这种现象是有限精度的产物。如果一个非常大数加上一个非常小数对大数并不会产生太大的影响。所以在计算时应该仔细选择计算的顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值