Search code examples
debuggingbinarybase-conversionti-basic

Complex Numbers Seemingly Arising from Non-Complex Logarithms


I have a simple program written in TI-BASIC that converts from base 10 to base 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

This will sometimes return an the error 'ERR: DATA TYPE'. I checked, and this is because the variable D, will sometimes become a complex number. I am not sure how this happens.

This happens with seemingly random numbers, like 5891570. It happens with this number, but not something close to it like 5891590 Which is strange. It also happens with 1e30, But not 1e25. Another example is 1111111111111111, and not 1111111111111120.

I haven't tested this thoroughly, and don't see any pattern in these numbers. Any help would be appreciated.


Solution

  • The error happens because you round the logarithm to one decimal place before taking the integer part; therefore, if log(D)/log(2) is something like 8.99, you will round E up rather than down, and 2^9 will be subtracted from D instead of 2^8, causing, in the next iteration, D to become negative and its logarithm to be complex. Let's walk through your code when D is 511, which has base-2 logarithm 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
    

    Rounding the logarithm any more severely than nine decimal places (nine digits is the default for round( without a "digits" argument) is completely unnecessary, as on my TI-84+ rounding errors do 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 high enough that precision would be lost anyway in other parts of the calculation.

    To fix your code, simply round only once, and only to nine places. I've also removed the unnecessary double-initialization of E, removed your close-parens (it's still legal code!), and changed the Repeat (which always executes one loop before checking the condition D=0) to a While loop to prevent ERR:DOMAIN when the input is 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
    

    Don't expect either your code or my fix to work correctly for D > 213 or so, because your calculator can only store 14 digits in its internal representation of any number. You'll lose the digits while you store the result into B!

    Now for a trickier, optimized way of computing the binary representation (still only works for D < 213:

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