2015-08-02 9 views
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.

Я не проверял это полностью и не вижу никаких рисунков в этих числах. Любая помощь будет оценена по достоинству.

ответ

2

Ошибка возникает из-за того, что вы обходите логарифм до одного десятичного знака, прежде чем принимать целочисленную часть; поэтому, если log(D)/log(2) что-то вроде 8.99, вы будете округлять E вверх, а не вниз, а 2^9 будет вычитаться из D вместо 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 для всего целого 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 или так, потому что ваш калькулятор может хранить только 14 цифр в своем внутреннем представлении любого числа , Вы потеряете цифры, пока сохраняете результат в B!

Теперь для хитроумного, оптимизированного способа вычисления двоичного представления (по-прежнему работает только для D :

Input D 
int(2fPart(D/2^cumSum(binomcdf(13,0 
.1sum(Ans10^(cumSum(1 or Ans 
+0

Running это на моем TI-83 Plus приводит к ошибкам из-за плавающую точку округления вопросов Например, 48, преобразуется в «102000» вместо «110000». Любая идея о том, как исправить это? –

+1

@JamieSanborn Если у вас был калькулятор серии TI-84 + с новейшей ОС, в функции logBASE (D, 2', которая исправляет ошибки округления для вас; в вашем случае замените 'int (log (D)/log (2' на' int (round (log (D)/log (2') , который округляет результат до девяти знаков после запятой (слишком мало для cau se, но достаточно большой, чтобы исправить их). Это будет работать только до 2^27, хотя (еще больше, чем максимальная точность вашего выходного формата). – lirtosiast

+0

Aha! Спасибо вам большое за это. Я новичок в TI-BASIC, и ваши небольшие оптимизации кода помогают тонне. :-) –