我有一个用TI-BASIC编写的简单程序,它从基数10转换为基数2
0->B
1->E
Input "DEC:",D
Repeat D=0
int(round(log(D)/log(2),1))->E
round(E)->E
B+10^E->B
D-2^E->D
End
Disp B
这有时会返回错误'ERR:DATA TYPE'。我查了一下,这是因为变量D有时会变成一个复数。我不确定这是怎么发生的。
这种情况发生在看似随机的数字上,如5891570.它发生在这个数字上,但不是像5891590那样接近它,这很奇怪。它也发生在1e30,但不是1e25。另一个例子是1111111111111111,而不是1111111111111120。
我没有彻底测试过,并且没有看到这些数字中的任何模式。任何帮助将不胜感激。
答案 0 :(得分:2)
发生错误是因为在取整数部分之前将对数舍入到小数点后一位;因此,如果log(D)/log(2)
类似于8.99
,则会向上E
向上而不是向下,2^9
将从D而不是2^8
中减去,导致,在下一次迭代中,D
变为负数,其对数变得复杂。当D为511
时,让我们遍历您的代码,8.9971
具有基数2对数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(
对数舍入至少小于9位小数(9位数是round(int(log(2^X-1)/log(2))
的默认值,没有"数字"参数)完全没必要,就像我的TI-84 +舍入误差一样不累积:round(int(log(2^X)/log(2))
返回X-1,E
返回X,表示所有整数X≤28,这足以使精度在计算的其他部分无论如何都会丢失。
要修复代码,只需绕一次,最多只能回合九个位置。我还删除了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
。
Input D
int(2fPart(D/2^cumSum(binomcdf(13,0
.1sum(Ans10^(cumSum(1 or Ans
不要期望您的代码或我的修复程序正常运行D> 2 13 左右,因为您的计算器只能在其任何数字的内部表示中存储14位数字。将结果存储到B中时,您将丢失数字!
现在有一种更为棘手,优化的计算二进制表示的方法(仍然只适用于D< 2 13 :
try