读《程序是怎么跑起来第3章》
将小数分为符号,尾数,基数,指数,4部分进行表现的形式称为浮点数。通过把0作为数值范围的中间值,从而在不使用符号位的情况下来,表示负数的表示方法称为Excess系统表现。将0.1累加100次也得不到10的出错原因是,是因为有一些十进制数的小数无法转换成二进制数。例如十进制数,0.1就无法用二进制数正确表示,小数点后面即使有几百位也无法表示。接下来我们看一个例子,表示一下不能种正确表示的原因。
1 #include<stdio.h> 2 3 void main() 4 { 5 float sum; 6 int i; 7 //将保存总和的变量清0 8 sum=0; 9 //0.1相加100次 10 for(i=0;i<100;i++) 11 { 12 sum+=0.1; 13 } 14 //显示结果 15 printf("%f\n",sum); 16 }
小数点后四位用二进制数表示时的数值范围为0.0000-0.1111,因此这里只能表示0.5、0.25、0.125、0.0625,这四个二进制小数点后面的位权组合而成(相加总和)将这些数值组合后能够表示的数值,即为下图所示的无序十进制数。
实际上十进制数0.1转换成二进制后会变成0.001100110011,这样的循环小数。
浮点数是指用符号、尾数、基数和指数这四部分来表示来小数,因为计算机内部使用的二进制数,所以基数自然就是2。因此实际的数据中往往不考虑基数,只用符号、尾数、指数这三部分即可表示浮点数。符号部分是指使用一个数据位来表示数值的符号,该数据位是1时表示负;为0时,则表示正或者0。这和二进制数来表示整数十的符号位是同样的。数字的大小用尾数部分和指数部分来表示。例如,小数就是用“尾数部分乘2的指数部分次幂”,这样的形式来表示的尾数部分和指数部分并不只是单单存储着用整数表示的二进制数。尾数部分用的是将小数点前面的值固定为1的正则表达式,而指数部分用的是Excess系统表现。
我们使用的是将小数点前面的值固定为1的正则表达制,具体来讲就是在二进制数表示的小数,左移或右移数次后整数部分的第一位变为1,第二位之后都变为0,而且第一位的1在实际的数据中不保存,由于第一位必须是1,因此,省略该部分后就接上了一个数据位,从而也就可以表示更多的数据范围。
Excess通过将指数部分表示范围的中间值设为零,使得负数不需要用符号来表示。
如何避免计算机计算出错,首先是回避策略,即无视这些错误;第二,是把小数转化成整数来计算;第三,BCD方式;第四,使用C#语言编写程序。
1 using System; 2 3 class test1 4 { 5 public static void Main() 6 { 7 float sum; 8 int i; 9 //将保存总和的变量清0 10 sum=0F; 11 //0.1相加100次 12 for(i=0;i<100;i++) 13 { 14 sum+=0.1F; 15 } 16 //显示结果 17 Console.WriteLine("sum is {0}",sum); 18 } 19 }