发生错误是因为在取整数部分之前将对数四舍五入到小数点后一位;因此,如果log(D)/log(2) 类似于8.99,您将向上而不是向下舍入E,并且将从D 中减去2^9 而不是2^8,从而导致在下一次迭代中D 变为变为负数,其对数为复数。当 D 为 511 时,让我们来看看你的代码,它的底数为 2 对数 8.9971:
Repeat D=0 ;Executes first iteration without checking whether D=0
log(D)/log(2 ;8.9971
round(Ans,1 ;9.0
int(Ans ;9.0
round(Ans)->E ;E = 9.0
B+10^E->B ;B = 1 000 000 000
D-2^E->D ;D = 511-512 = -1
End ;loops again, since D≠0
---next iteration:----
log(D ;log(-1) = 1.364i; throws ERR:NONREAL ANS in Real mode
完全没有必要将对数舍入超过九位小数(round( 没有“数字”参数的默认值是九位),因为在我的 TI-84+ 上舍入错误不会累积:round(int(log(2^X-1)/log(2))返回 X-1 和 round(int(log(2^X)/log(2)) 为所有整数 X≤28 返回 X,这足够高,以至于在计算的其他部分无论如何都会丢失精度。
要修复您的代码,只需四舍五入一次,并且只四舍五入到九个位置。我还删除了E 的不必要的双重初始化,删除了你的近括号(它仍然是合法代码!),并将Repeat(在检查条件D=0 之前总是执行一个循环)更改为While循环防止ERR:DOMAIN当输入为0时。
0->B
Input "DEC:",D
While D
int(round(log(D)/log(2->E
B+10^E->B
D-2^E->D
End
B ;on the last line, so it prints implicitly
不要期望您的代码或我的修复程序在 D > 213 左右都能正常工作,因为您的计算器只能在其内部表示的任何数字中存储 14 位数字。当您将结果存储到 B 中时,您会丢失数字!
现在提供一种计算二进制表示的更复杂、优化的方法(仍然只适用于 D 13:
Input D
int(2fPart(D/2^cumSum(binomcdf(13,0
.1sum(Ans10^(cumSum(1 or Ans