UVa 11809 - Floating-Point Numbers

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=830&page=show_problem&problem=2909

 

这是道数学题啊!!!! 数学渣表示好慌【瑟瑟发抖

 

我们可知0<=m<=9,1<=e<=30,数据比较小,打表解决。

首先我们要知道浮点数在计算机里是分三部分表示的,最前面一位表示符号,后面一部分是尾数,最后一部分是阶码,表示方法类似于科学记数法,不过是二进制的。

(1)若有m位尾数,则实际表示的尾数为:a=2^(-1)+2^(-2)+2^(-3)+...+2^(-m-1)=1-2^(-m-1);(自带一位尾数)。

(2)若有e位阶码,则实际指数为2^b=2^(2^e-1);

设十进制形式下尾数为c,指数为d,则:a * 2^b = c * 10^d。

我们现在可将两边同时取以10为底的对数,得:

log10(a) + b * log10(2) = log10(c) + d;

因为科学计数法要求1<=c<10,所以0<=log10(c)<1,且d为整数,则可得d=floor(x);则c = 10^(x - d)。

对任意输入的p * 10^q,查表逐个匹配,只要q = d且fabs(p - c)小于给定误差(1*10^(-5)),即可认为查找成功,输出对应的m和e。

 

注:floor()函数为向下取整。定义变量时一定要注意数据类型!!

 

附AC代码:

 1 #include <iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     double A[10][31];
10     double a,c;
11     double x;
12     long long B[10][31];
13     long long b,d;
14     int i,j;
15     for(i=0;i<10;i++)
16         for(j=1;j<31;j++){//打表 
17             a=1-pow(2,-i-1);
18             b=pow(2,j)-1;
19             x=log10(a)+b*log10(2);
20             d=floor(x);
21             c=pow(10,x-d);
22             A[i][j]=c;
23             B[i][j]=d;
24         }
25 
26     char s[30];
27     double p;
28     int q;
29     
30     while(cin>>s){
31         if(s=="0e0")
32         return 0;
33         s[17]=' ';//将e变为空格 
34         sscanf(s,"%lf %d",&p,&q);//从s读入p,q 
35         for(i=0;i<10;i++)
36             for(j=1;j<31;j++)
37                 if(fabs(A[i][j]-p)<1e-5&&B[i][j]==q)//匹配输出 
38                     cout<<i<<' '<<j<<endl;
39     }
40     return 0;
41 }

 

posted @ 2016-07-15 16:47  Kiven#5197  阅读(571)  评论(0编辑  收藏  举报