看似由非复数对数产生的复数
Complex Numbers Seemingly Arising from Non-Complex Logarithms
我有一个用 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
这有时会 return 错误 'ERR: DATA TYPE'。我检查了一下,这是因为变量 D,有时会变成一个复数。我不确定这是怎么发生的。
这发生在看似随机的数字上,比如 5891570。它发生在这个数字上,但不是接近它的数字,比如 5891590 这很奇怪。它也会发生在 1e30 上,但不会发生在 1e25 上。另一个例子是 1111111111111111,而不是 1111111111111120。
我还没有对此进行彻底的测试,也没有在这些数字中看到任何规律。任何帮助将不胜感激。
这个错误是因为你在取整数部分之前把对数四舍五入到小数点后一位;因此,如果 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
完全没有必要将对数四舍五入到小数点后九位(没有 "digits" 参数的 round(
默认为九位),因为我的 TI-84+ 舍入错误确实如此not accumulate: round(int(log(2^X-1)/log(2))
returns X-1 and round(int(log(2^X)/log(2))
returns X for all integer X≤28, which is is high enough that precision would lost anyway in the other parts of the other parts计算。
要修复您的代码,只需四舍五入一次,并且只到九个地方。我还删除了 E
不必要的双重初始化,删除了闭括号(它仍然是合法代码!),并更改了 Repeat
(它总是在检查条件 [= 之前执行一个循环) 26=]) 到 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 < 213:
Input D
int(2fPart(D/2^cumSum(binomcdf(13,0
.1sum(Ans10^(cumSum(1 or Ans
我有一个用 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
这有时会 return 错误 'ERR: DATA TYPE'。我检查了一下,这是因为变量 D,有时会变成一个复数。我不确定这是怎么发生的。
这发生在看似随机的数字上,比如 5891570。它发生在这个数字上,但不是接近它的数字,比如 5891590 这很奇怪。它也会发生在 1e30 上,但不会发生在 1e25 上。另一个例子是 1111111111111111,而不是 1111111111111120。
我还没有对此进行彻底的测试,也没有在这些数字中看到任何规律。任何帮助将不胜感激。
这个错误是因为你在取整数部分之前把对数四舍五入到小数点后一位;因此,如果 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
完全没有必要将对数四舍五入到小数点后九位(没有 "digits" 参数的 round(
默认为九位),因为我的 TI-84+ 舍入错误确实如此not accumulate: round(int(log(2^X-1)/log(2))
returns X-1 and round(int(log(2^X)/log(2))
returns X for all integer X≤28, which is is high enough that precision would lost anyway in the other parts of the other parts计算。
要修复您的代码,只需四舍五入一次,并且只到九个地方。我还删除了 E
不必要的双重初始化,删除了闭括号(它仍然是合法代码!),并更改了 Repeat
(它总是在检查条件 [= 之前执行一个循环) 26=]) 到 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 < 213:
Input D
int(2fPart(D/2^cumSum(binomcdf(13,0
.1sum(Ans10^(cumSum(1 or Ans