计算机系统基础日志No.7 大数吞小数
文章目录
一,程序及编译运行结果1.源程序2.编译运行3.分析
二,拓展1.关于浮点数的存储方式的具体解释2.atof函数
一,程序及编译运行结果
1.源程序
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 256
int main(int argc, char *argv[]) {
char prefix[BUFSIZE];
char next[BUFSIZE];
int i;
float sum = 0.0;
for (i = 1; i < argc; i++) {
float x = atof(argv[i]);
sum += x;
if (i == 1) {
sprintf(prefix, "%.4g", x);
} else {
sprintf(next, " + %.4g", x);
strcat(prefix, next);
printf("%s = %.4g\n", prefix, sum);
}
}
return 0;
}
2.编译运行
lwh@lwh-virtual-machine:~$ gcc fsum.c
lwh@lwh-virtual-machine:~$ gcc fsum.c -o fsum
lwh@lwh-virtual-machine:~$ ./fsum 1e20 -1e20 3.14
1e+20 + -1e+20 = 0
1e+20 + -1e+20 + 3.14 = 3.14
lwh@lwh-virtual-machine:~$ ./fsum -1e20 3.14
-1e+20 + 3.14 = -1e+20
lwh@lwh-virtual-machine:~$ ./fsum -1e20 3.14 1e20
-1e+20 + 3.14 = -1e+20
-1e+20 + 3.14 + 1e+20 = 0
3.分析
浮点数在运算时,会有一个对齐问题,这样在非常大的数和3.14相加时,会舍掉有效位,然后只剩le20了
二,拓展
1.关于浮点数的存储方式的具体解释
可以参考《深入了解计算机》和来自jillzhang的解释(如下)
C语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。
无论是单精度还是双精度在存储中都分为三个部分:
1.符号位(Sign) : 0代表正,1代表为负 2.指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储 3.尾数部分(Mantissa):尾数部分 其中float的存储方式如下图所示: 而双精度的存储方式为:
2.atof函数
double atof(const char *str) 把参数 str 所指向的字符串转换为一个浮点数(类型为 double 型)。