UVa 11809 Floating-Point Numbers (浮点数)

博客详细介绍了浮点数的二进制存储方式,包括尾数和阶码的组成,并针对UVa 11809题目,提出了用打表方法解决最大浮点数问题的策略。通过预先计算每个尾数位数M和阶码位数E对应的最大浮点数,然后利用对数进行转换,简化计算,避免了大量重复计算。同时,博客还讲解了如何使用sscanf函数从字符串中提取所需信息。

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


题意:

先介绍了浮点数的存储---用二进制数存储。浮点数(n)由尾数(mantissa)和阶码(exponent)组成。假设尾数和阶码的位数分别为M和E。按从左至右的顺序,首先是尾数的符号位(0代表正数,1代表负数),接下来是M位尾数部分,由于存储时尾数部分值一定是属于区间[0.5,1),所以M位尾数部分的第一位也就是整体的第二位一定是1。当M位尾数存储完了,第M+1位是阶码的符号位(0代表正数,1代表负数)。然后剩余E位用以保存阶码值。

例如:当M=8,E=6时,可以表示的最大浮点数(二进制)是

利用二进制和十进制的转化规则可以将之转化为:

现在给出一个最大浮点数(用科学计数法AeB表示,且A有效数字15位),问存储时的尾数位数M和阶码位数E个位多少?

其中M取值区间[0,9],E取值区间[1,30]。

测试数据大概300行,0e0结束输入。

分析:

显然对于300行输入数据而且E的结果很可能很大,如果一个一个计算的话,会出现大量重复计算。可以用打表的方法:

预处理每个M和每个E对应的最大浮点数是多少,共300种匹配,然后对于每个输入,查找即可。

a[i][j]表示尾数位数为i,阶码位数为j时存储的最大浮点数。最大浮点数时,除了符号位其余位上都是1。

尾数部分存储数值为m[i],阶码部分存储数值为e[i][j]。通过二进制和十进制转换可得:m[i]=1-(1/2)^(i+1);e[j]=2^j-1;且a[i][j]=m[i]*2^(e[j])

但是如果这样直接存储数值太大了,所以取对数可得a[i][j]=>log10(m[i])+e[j]*log10(2),这样就可以打表了。

如果输入用AeB即A*10^B表示的话,也取对数可得log10(A)+B=t;

对于每个输入只需查找a[i][j]==t,输出对应的m[i]和e[j]即可。
至于A,B如何获取可以用sscanf函数。

sscanf函数的用法:

  sscanf() - 从一个字符串中读进与指定格式相符的数据. 
  函数原型: 
  Int sscanf( string str, string fmt, mixed var1, mixed var2 ... ); 
  int scanf( const char *format [,argument]... ); 
  说明: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值