题意
思路
假设该数字表示为
X
∗
2
Y
X*2^Y
X∗2Y,那我们要求解的就是
X
∗
2
Y
=
A
∗
1
0
B
X*2^Y=A*10^B
X∗2Y=A∗10B,M=(X的位数),E=(Y的位数)
如果直接去计算这个数字的话会很大,因为Y有30位长,这个数大概也就是
2
1
0
30
2^{10^{30}}
21030肯定是会炸的,所以想办法把这个数字去缩小一下,很容易想到使用
l
o
g
log
log取对数的方式。
l
o
g
10
(
X
∗
2
Y
)
=
l
o
g
10
(
A
∗
1
0
B
)
log_{10}(X*2^Y)=log_{10}(A*10^B)
log10(X∗2Y)=log10(A∗10B) =>
l
o
g
10
(
X
)
+
Y
∗
l
o
g
10
2
=
l
o
g
10
(
A
)
+
B
log_{10}(X)+Y*log_{10}2=log_{10}(A)+B
log10(X)+Y∗log102=log10(A)+B
因为题目中说这个数是一个尾码长度为为M,阶码长度为E最大的浮点数,那么
Y
=
2
E
−
1
Y=2^E-1
Y=2E−1,
X
=
2
−
1
+
2
−
2
+
…
+
2
−
1
−
M
X = 2^{-1} + 2^{-2} + … + 2^{-1-M}
X=2−1+2−2+…+2−1−M =>
X
=
1
−
2
−
1
−
M
X = 1-2^{-1-M}
X=1−2−1−M。
我们通过枚举答案 M 和 E 求得 X 和 Y ,如果符合
l
o
g
10
(
X
)
+
Y
∗
l
o
g
10
2
=
l
o
g
10
(
A
)
+
B
log_{10}(X)+Y*log_{10}2=log_{10}(A)+B
log10(X)+Y∗log102=log10(A)+B,那么就是答案。
注意可能会有精度损失,所以判断两个数字相等的时候不能直接用==,而是当误差小于某个值时就认为相等。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-7;
int main()
{
char s[30];
while (~scanf("%s%*c", s) && strcmp(s, "0e0") != 0)
{
LL A = s[0]-'0', B = 0;
for (int i = 2; i < 17; i++) A = A*10+s[i]-'0';
for (int i = 18; i < strlen(s); i++) B = B*10+s[i]-'0';
double t = log10(A)+B-15;
bool flag = false;
for (int i = 0; i < 10; i++)
{
for (int j = 1; j <= 30; j++)
{
double X = 1 - pow(2, -1-i), Y = pow(2, j)-1;
double ans = log10(X)+Y*log10(2);
if (fabs(ans - t) < eps)
{
flag = true;
printf("%d %d\n", i, j);
break;
}
}
if (flag) break;
}
}
return 0;
}
/*
5.699141892149156e76
9.205357638345294e18
0e0
*/