刘汝佳算法竞赛入门 UVA-11809 Floating-Point Numbers 暴力写法。

 

题目大意:计算机常用阶码-尾数的方法保存浮点数。如 图3-9所示,如果阶码有6位,尾数有8位,可以表 达的最大浮点数为0.1111111112×21111112。注意小 数点后第一位必须为1,所以一共有9位小数。

 

这个数换算成十进制之后就是 0.998046875263=9.2053576383452941018。你的 任务是根据这个最大浮点数,求出阶码的位数E 和尾数的位数M。输入格式为AeB,表示最大浮 点数为A*10^B。0<A<10,并且恰好包含15位有效 数字。输入结束标志为0e0。对于每组数据,输 出M和E。输入保证有唯一解,且0≤M≤9, 1≤E≤30。在本题中,M+E+2不必为8的整数倍。

在第一次看见这道题的时候,确实没什么思路。但是细想后,也并不是毫无头绪。

首先,我们分析后知道,输出的是阶码和位数,并且题目的数据比较小。那么我们要从哪方面入手呢。

没错就是进制,通过二进制转十进制的思路,我们从数学的思路分析。m = 2^(-1) + 2^(-2) + … + 2^(-1 - i)(i比实际1的个数少1个),所以从等比数列的性质(错位相减求前n项和),我们求出m = 1 - 2^(-1 - i)。二进制的阶码,我们可以从相同的方式推出,e=(2^n)-1均由数学等比数列推出,可自行推导e,不要懒,多思多动手才能进步.0^0)。那么现在就简单多了。我们只需根据m * 2^e = A * 10^B计算就行了?当然不会这么简单了。

首先要考虑的就是数据范围为问题当e比较大的时候,会炸long long 的范围,导致我们的结果出错。其次就是误差的问题,由次数幂的关系可知,左右两边很难完全相同,所以我们要控制一定的误差。在此基础上,我们可以通过将两式相等来简化问题。至于数据的问题,我们需要数学函数(log)的帮助。对两边同时对10取对数。(等号是近似取的,一定要注意)。

当时有人问过我,m和e的范围都不过32,为什么会炸,这里解释一下,那个范围是二进制的数字个数,转为10进制,2的指数最大大概为1073741823。所以数据范围会出错。

 那么现在我们的问题就简单多了。我们把右边的式子设为未知数x;然后判断两式相减是否在一个允许的误差内。即(log10(m)+e*log10(2)-x)<1e-5。成立即可;

另外输入时候,有些写法是用字符串储存浮点数,使用了sscanf进行分割。但是本题的输入可以简化。只要用scanf和double。这一题还可以打表计算,将所有可能的值储存在二维数组内,寻找最接近的一个值。最后暴力ac的代码贴下。

#include<stdio.h>
#include<math.h>
#include<cmath>
using namespace std;
int main()
{
	double a;
	int b;
	while(scanf("%17lfe%d",&a,&b)&&(a!=0))//注意输入的时候用%17lf卡极限,%16lf的部分输出会出错。
	{
		int m,e;
		double k,t;
		double x=log10(a)+b;
		int l=1;// 标记;
		for(m=0;m<=9;m++)
		{
			k=1-pow(2,-(m+1));
			for(e=0;e<=30;e++)
			{
				t=pow(2,e)-1;
				if((log10(k)+t*log10(2)-x)<1e-5&&(log10(k)+t*log10(2)-x)>-(1e-5))//精度判断,可以用abs函数简化。
                {//abs(log10(k)+t*log10(2)-x)<1e-5
                    l=0;//满足条件即可输出。
					break;
                }
			}
			if(l==0) 
			break;
		}
		printf("%d %d\n",m,e);
	}
}

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值