csapp学习笔记(大数吃小数)

#include <stdio.h>
#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);/!sprintf格式化输出
	  %g将采用可以表示为%f(简单浮点数或双精度数)或%e(科学计数法)的数字,
	  并从两者中选择合适的。!/
	  } else {
	  sprintf(next, " + %.4g", x);
	  strcat(prefix, next);
	  printf("%s = %.4g\n", prefix, sum);
	}
    }
    return 0;
}
/*
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out 1e20 -1e20 3.14
1e+20 + -1e+20 = 0
1e+20 + -1e+20 + 3.14 = 3.14
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out -1e20 3.14
-1e+20 + 3.14 = -1e+20
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out -1e20 3.14  1e20
-1e+20 + 3.14 = -1e+20
-1e+20 + 3.14 + 1e+20 = 0
*/

例程注释

相信没有接触过linux的人可能会对int main(int argc, char argv[]) 有所困惑,这个统一注释下
第一个int argc,是记录你输入在命令行上的字符串个数;
第二个
argv[]是个指针数组,存放输入在命令行上的命令(字符串)。
argv[]是一个字符数组.
argv[0]:指向程序的名称
argv[1]:指向程序名后的第一个字符串。
②对于atof,这是c的一类自带库函数
atof:将字符串转成float型;atoi:字符串转成int型;atol:将字符串转成long型
同理,对于strcat是c自带库函数(string里的)
strcat的用法:strcat(字符串1,字符串2)
strcat是一个函数.是字符串连接的意思. 起作用是连接两个字符数组中的字符串.
把字符串2接到字符串1的后面.结果放在字符串1中.
这个函数调用后得到一个函数值:字符串1的地址

看完程序我们来看看结果
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out -1e20 3.14
-1e+20 + 3.14 = -1e+20
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out -1e20 3.14 1e20
-1e+20 + 3.14 = -1e+20
-1e+20 + 3.14 + 1e+20 = 0
在这段结果中我们很明显的看到了大数吃小数的情况发生,在解释这个情况之前读者最好掌握浮点数是怎么存储的和浮点数的加法,了解了之后在来看下面的解释。
情况解释
掌握浮点数加法后原因其实很简单,就是在对阶时我们会对尾数进行位移以此保证改变阶码后数的值仍不变,我们设想相加的两个数阶码差过大,对阶时就会出现小的数尾数进行位移操作后全部为0,所以小数就为0了,看起来就像小数被大数吃掉了。

发布了30 篇原创文章 · 获赞 5 · 访问量 6952

猜你喜欢

转载自blog.csdn.net/weixin_44735312/article/details/90578342