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

本文通过分析C程序中浮点数的加法操作,揭示了在特定情况下大数会“吃掉”小数的现象。讨论了int argc, char *argv[]在命令行参数中的作用,并介绍了atof等字符串转换函数以及strcat字符串连接函数的用法。通过实例展示了浮点数加法导致的小数消失问题,并解释了其背后的原理,即在对阶过程中小数的尾数位移后变为0。" 119065701,11275180,Eclipse安装与配置指南,"['开发工具', 'Eclipse', 'Java']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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了,看起来就像小数被大数吃掉了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值