2

我有一个用 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:数据类型”。我查了一下,这是因为变量D,有时会变成复数。我不确定这是怎么发生的。

这发生在看似随机的数字上,比如 5891570。它发生在这个数字上,但不是像 5891590 这样接近它的数字,这很奇怪。它也发生在 1e30 上,但不是 1e25。另一个例子是 1111111111111111,而不是 1111111111111120。

我还没有彻底测试过,在这些数字中看不到任何模式。任何帮助,将不胜感激。

4

1 回答 1

2

发生错误是因为您在取整数部分之前将对数四舍五入到小数点后一位;因此,如果log(D)/log(2)类似于8.99,您将E向上取整而不是向下取整,并且2^9将从 D 中减去而不是2^8,从而导致在下一次迭代D中变为负数并且其对数变得复杂。让我们在 D is 时浏览您的代码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整数 X≤28,它足够高,以至于在计算的其他部分无论如何都会丢失精度。

要修复您的代码,只需四舍五入一次,并且只四舍五入到九个位置。我还删除了不必要的双重初始化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 > 2 13左右时正常工作,因为您的计算器只能在其内部表示的任何数字中存储 14 位数字。当您将结果存储到 B 中时,您会丢失数字!

现在对于计算二进制表示的更复杂、优化的方法(仍然只适用于 D < 2 13

Input D
int(2fPart(D/2^cumSum(binomcdf(13,0 
.1sum(Ans10^(cumSum(1 or Ans
于 2015-08-03T00:58:18.600 回答