SilentSpiral

浮点数对阶

问题

密码学老师曾经给大家出过这样一个问题: 人力运行如下代码, 求其最终输出

1
2
3
4
5
6
7
8
9
10
11
12
#define IV 2.718
double e,e2,x,y;
e=IV;
e2=e;
x=0;
y=1;
for (i=0;x!=y;i++){
y=x;
e2=e2/2;
x=e2+y;
}
printf("%d",i);

在数学上这个循环将不可能跳出 但计算机里可以 具体来说, 这个问题是浮点数加法对阶的问题 注意到四个变量都是double类型,即双精度浮点数

1位 11位 52位
S(符号位), 编号63 E(阶码位), 编号62~52 M(尾数位), 编号51~0
0表示正,1表示负 1~2046 任意

尾数部分的精度是52个bit, 用以存储去掉小数点后的二进制数字首位的1以后的部分
首位的1是默认存在的, 不必存储在尾数中
可以认为小数点点在尾数的第一位与看不见的1之间
加法运算时, 需要对齐小数点再做运算
若阶码相差n位, 则较小者需右移n位, 补上看不见的1以后可进行运算

当参与运算的两个浮点数的阶码相差53或以上时,对阶过程会使小的浮点数尾数部分连同看不见的1全部变为0,即小的浮点数被视为0,结果仍为较大的浮点数

answer = 53

打赏