紫书第三章训练 UVA 11809 Floating-Point Numbers by 16 BobHuang

Floating-point numbers are represented differently in computers than integers. That is why a 32-bitfloating-point number can represent values in the magnitude of 10^38 while a 32-bit integer can onlyrepresent values as high as 2^32.

Although there are variations in the ways floating-point numbers are stored in Computers, in thisproblem we will assume that floating-point numbers are stored in the following way:

Floating-point numbers have two parts mantissa and exponent. M-bits are allotted for mantissaand E bits are allotted for exponent. There is also one bit that denotes the sign of number (If thisbit is 0 then the number is positive and if it is 1 then the number is negative) and another bit thatdenotes the sign of exponent (If this bit is 0 then exponent is positive otherwise negative). The value ofmantissa and exponent together make the value of the floating-point number. If the value of mantissais m then it maintains the constraints 12 ≤ m < 1. The left most digit of mantissa must always be 1 tomaintain the constraint 12 ≤ m < 1. So this bit is not stored as it is always 1. So the bits in mantissaactually denote the digits at the right side of decimal point of a binary number (Excluding the digitjust to the right of decimal point)

In the figure above we can see a floating-point number where M = 8 and E = 6. The largest valuethis floating-point number can represent is (in binary)

0.111111111(2)×2^111111(2). The decimal equivalentto this number is: 0.998046875 × 2^63 = 9205357638345293824(10). Given the maximum possible valuerepresented by a certain floating point type, you will have to find how many bits are allotted formantissa (M) and how many bits are allotted for exponent (E) in that certain type.

Input

The input file contains around 300 line of input. Each line contains a floating-point number F thatdenotes the maximum value that can be represented by a certain floating-point type. The floating pointnumber is expressed in decimal exponent format. So a number AeB actually denotes the value A×10^B.A line containing ‘0e0’ terminates input. The value of A will satisfy the constraint 0 < A < 10 andwill have exactly 15 digits after the decimal point.

Output

For each line of input produce one line of output. This line contains the value of M and E. You canassume that each of the inputs (except the last one) has a possible and unique solution. You can alsoassume that inputs will be such that the value of M and E will follow the constraints: 9 ≥ M ≥ 0 and30 ≥ E ≥ 1. Also there is no need to assume that (M + E + 2) will be a multiple of 8.

Sample Input

5.699141892149156e76
9.205357638345294e18
0e0

Sample Output

5 8
8 6
 
这道题很熟悉,它用科学计数法表示了一个数,你需要计算它的尾数和它的阶码所需的最小位数,这个题是自己找到别人的题解才做出来的。我当时处理e用string转换出了点
问题,说什么这个头文件里不包括这个函数,只好就有c语言的sscannf了,一查其实是c++标准的问题
300行还是不小的,需要先用打表把需要的数据
都预理下,然后比较找到i,j就直接输出。
我来写下我的理解,"0.111111111(2)×2^111111(2). The decimal equivalentto this number is: 0.998046875 × 2^63 = 9205357638345293824(10). "
我们要得到某个i位二进制的尾数,需要对其十进制的尾数进行分析,因为1/2+1/4+……+1/2n=1-1/2n,所以这个就很明显了吧,我得到的m的值就是我用二进制表示的数值,某个
j为二进制数的阶码,表示的指数e为2^j-1,这个都明白了吧,我需要和我的值联系起来,E要存阶码2^e=2^[2^j-1],移向整理得m*2^e=c*10^d用log10处理下,所得t
取整就是你要算的阶码,尾码就是10的t的小数部分次方啊
下面这个是那个老哥的推理,不懂预处理的可以看下,理解这个是这道题的关键,但是其实也就是数学,要用log10处理下,想不明白的可以私聊我
因为位数自带一个1,这个1是不被存储的,所以对于某个i位二进制数的尾数,它的十进制尾数值m=1-2^(-i-1)对于某个j位二进
制数的阶码,可表示的指数为2^e=2^[2^j-1]然后把这个数转换成对应的以10为底的计数法表示出来(未知数已假设),m*2^e=c*10^d,解这个指数幂等式首先想到的是两
边取常用对数,得到log10(m)+e*log10(2)=log10(c)+d,先令左边为t,则d=t-log10(c),因为1<=c<10,所以log10(c)<1,因为d为指数,为正,所以d=t的取整。
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 double M[10][31];
 4 int E[10][31];
 5 void la()
 6 {
 7     for(int i=0;i<10;i++)
 8     {
 9         for(int j=1;j<31;j++)
10         {
11             double m=1.0-1.0/(1<<(i+1));
12             int e=(1<<j)-1;
13             double t=log10(m)+e*log10(2);
14             E[i][j]=(int)t;
15             M[i][j]=pow(10,t-E[i][j]);
16         }
17     }
18 }
19 int main()
20 {
21     double m;
22     int e;
23     la();
24     char s[105];
25     while(gets(s)&&strcmp(s,"0e0"))
26     {
27         for(int i=0;s[i];i++)
28         if(s[i]=='e') s[i]=' ';
29         sscanf(s,"%lf %d",&m,&e);
30         int f=0;
31         for(int i=0;i<10;++i)
32         {
33             for(int j=1;j<31;++j)
34             {
35                 if(fabs(M[i][j]-m)<1e-5&&e==E[i][j])
36                 {
37                     f=1;
38                     printf("%d %d
",i,j);
39                     break;
40                 }
41             }
42             if(f)
43                 break;
44         }
45     }
46     return 0;
47 }
原文地址:https://www.cnblogs.com/tzcacm/p/6801494.html