最小化数值误差

来源:互联网 发布:unity3d vr材质 编辑:程序博客网 时间:2024/04/30 03:22

下面有一段程序是计算从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
原创粉丝点击