由于0<=m<=9,1<=e<=30,首先可通过一个表记录所有m和e的组合可得到的最大值及其十进制科学计数法形式下的尾数和指数。
二进制浮点数情况下:
(1)若有m位尾数,则实际表示尾数为a = 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。
令等式左边等于x,由于科学计数法要求1<=c<10,定有 log10(c) <= 0,且d为整数,则d = floor(x),那么c = 10^(x - d)。
对任意输入的p * 10^q,查表逐个匹配,只要q = d且fabs(p - c)小于给定误差(由于浮点数精度误差),即可认为查找成功,输出对应的m和e。
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
int main()
{
//freopen("input.txt","r",stdin);
double M[10][31],a,c,x;
long long int E[10][31],b,d;
int i,j;
for(i=0;i<=9;i++)
for(j=1;j<=30;j++){
a=1-pow(2,-(i+1));
b=pow(2,j)-1;
x=log10(a)+b*log10(2);
d=floor(x);
c=pow(10,x-d);
M[i][j]=c;
E[i][j]=d;
}
char s[30];
double p;
int q;
while(cin>>s){
if(s=="0e0")
break;
s[17]=' ';
sscanf(s,"%lf %d",&p,&q);
for(i=0;i<10;i++)
for(j=1;j<=30;j++)
if(fabs(M[i][j]-p)<1e-4&&E[i][j]==q)
cout<<i<<' '<<j<<endl;
}
return 0;
}