How to calculate ln(x)?

How to calculate natural logarithm of a number with propeller·and get the answer as an integer?
For example
ln(5) = ? (answer like 699/1000 is wanted)
and ln(5/7) = ?
Have looked DynamicMathLib object and "Accessing Math Function Tables" on the end of propeller manual. But still no success. Are there any examples for using these?


  • 4 Comments sorted by Date Added Votes
  • Mike GreenMike Green Posts: 22,577
    edited April 2007 Vote Up0Vote Down
    Have a look at this document ("Propeller Guts"):
  • Tracy AllenTracy Allen Posts: 6,103
    edited April 2007 Vote Up0Vote Down
    What is the range of values you will encounter? You mentioned ln(5) and ln(5/7).

    The table in ROM is 2048 words that represent the mantissa (fractional part) of the base 2 logarithm. So using those tables you will first calculate a log base 2, and then multiply times 0.69315 in order to convert to natural log.

    In the case of ln(5), you first find the integer part (characteristic) of the base 2 logarithm. Your number 5 lies between 4 and 8, so the characteristic is 2. Then you find proportionately where 5 lies between 4 and 8, and then use that as an index into the table in the HUB rom. The proportion in this case is (5-4)/4 = 0.25. The table is 2048 words long, so the address you want in the table is 0.25 * 2048 = 512. The Spin command to read the table then would be,

    result := word[noparse][[/noparse][noparse][[/noparse]$C000+ 512]

    The value returned would be 21097 as a 16 bit binary number, which you can consider as a binary fraction with the binary radix point on the left, or equivalently you can consider it as the fraction 21097/65536. ( (I calculated that number off the noggin; need to verify.) Combining the characteristic and the mantissa, you get.

    2_21097/65536, which is = 2.3219 in decimal

    In the Propeller, you can represent it in one long by putting the 2 in the high word and the fractional part in the low word. All this is described in the document Mike pointed out in slightly different terms, and with an ASM program.

    The natural log you want is
    ln 5 = 1.60945
    To convert from base 2 to the natural log, mutiply times 0.69315. That can be done using the Spin ** operator. The constant to use with ** will depend on the base you want the answer to end up in. Going in, the answer is represented as a fraction normalized to 2^16,
    log2(x) = y/65536.
    Going out, maybe you want your answer in base 10 as a integer y normalized to an implicit decimal factor, say 10000.
    ln(x) = y/10000.

    There are a couple of ways you could find ln(5/7). One would be to calculate ln(5) - ln(7).

    Tracy Allen

    Post Edited (Tracy Allen) : 4/1/2007 5:45:53 PM GMT
  • That was a lot of help smile.gif
    ASM is still behind mountains but bit shifting becomes clearer.
    The following code calculates the ln(x)*10000 of an integer number from 1 to $FFFFFFFF
    I plan to use it to calculate the temperature of thermistor·which·resistance can be obtained by RCTIME.

    PUB ln(x) | integer, bchange, fraction                  ' calculates natural logarithm*10000 of positive integer  
                                                            ' from 1 to $FFFFFFFF using Log Table
       integer := >|x - 1                                   ' calculating integer by the leading byte position
       bchange := x <- (11- integer)                        ' the address of fraction by proportional extrapolation
       fraction := word[noparse][[/noparse]$C000 + (bchange &= %11111111111)*2]     ' finding the fraction
       result := ((integer*6931 + fraction * 6931 / $10000) + (integer*6932 + fraction * 6932 / $10000))/2
                                                            ' combining results and multiplication by ln2
                                                            ' two additons to get 0.69315 without overriding

    Post Edited (fromouterelectronorbital) : 4/2/2007 4:16:39 PM GMT
Sign In or Register to comment.