Shop OBEX P1 Docs P2 Docs Learn Events
Odd request... Anybody have log10 in spin? — Parallax Forums

Odd request... Anybody have log10 in spin?

Stephen MoracoStephen Moraco Posts: 321
edited 2009-07-21 09:20 in Propeller 1
I'm working through turning on a propeller-based prototype. XBee radio, SHT11 sensor,
additional Analog Temp Sensor (so I can checkout XBee ADC and auto-reporting) and
headers for adding more sensors.

See: picasaweb.google.com/smmoraco/PropSenseAPropellerZigBeeBasedSensorPlatform

As I grabbed code from our object exchange SHT11, XBee etc... TV out (of course!) my own
serial and full-duplex serial (ok, I'll proably drop to only one of these and not mine as I don't
need the high speed).... I find that the SHTxx code is using float32 (asm in own cog) for only
the Log10 code. I have no performance need and believe it or not I could use a freed up
cog! (ok, stop laughing... I know, eight really should be enough... wink.gif

So, does anybody know of a spin-only version I can "leverage"?

Stephen, KZ0Q
--

Comments

  • TimmooreTimmoore Posts: 1,031
    edited 2009-07-21 07:17
    I did a ln rather than a log10 a while ago. It was a table lookup with linear interpolation. Not particular accurate but good enough for what I needed. The same system would work for this with a different tables.
    It was 2 tables, a table of x values and a table of ln(x) values. You walked though the x table until you found a value >= x then got ln (i-1) and ln(i) then did a linear interpolation of the 2 values.
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-21 07:46
    The ln can be aproximated with:

    ln x = 2 * [noparse][[/noparse](x-1) / (x + 1) + (x - 1)^3 / 3(x+1)^3 + (x - 1)^5 / 5(x + 1)^5 + ... ]

    for x > 0

    ln N = 2.30259 log N


    hth
    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • cessnapilotcessnapilot Posts: 182
    edited 2009-07-21 09:20
    Or, you can combine Timmoore's and Nick's method:

    Find the closest x0 to your x in the table of x values

    Then use the Taylor expansion

    log(x) approx.= ln(x0)/ln(10) + (x-x0)/(x0*ln(10)) - (x-x0)*(x-x0)/(2*x0*x0*ln(10))
    ····························|
    ···············[noparse][[/noparse]from the 2nd table]

    The 1/x0*ln(10) and· 1/(2*x0*x0*ln(10) constants could be
    stored in other tables, if you prefer speed.·

    Many depend on how the numbers are represented in your system and what is the range for x.

    If you have time enough to make something really effective, translate into SPIN the following c code, which does not use multiplication/division at all.

    Here x and ln(x) are both expressed as 32-bit fixed-point values with 16 fractional bits.

    int ln(int x) {
    int t,y;
    y=0xa65af;
    if(x<0x00008000) x<<=16, y-=0xb1721;
    if(x<0x00800000) x<<= 8, y-=0x58b91;
    if(x<0x08000000) x<<= 4, y-=0x2c5c8;
    if(x<0x20000000) x<<= 2, y-=0x162e4;
    if(x<0x40000000) x<<= 1, y-=0x0b172;
    t=x+(x>>1); if((t&0x80000000)==0) x=t,y-=0x067cd;
    t=x+(x>>2); if((t&0x80000000)==0) x=t,y-=0x03920;
    t=x+(x>>3); if((t&0x80000000)==0) x=t,y-=0x01e27;
    t=x+(x>>4); if((t&0x80000000)==0) x=t,y-=0x00f85;
    t=x+(x>>5); if((t&0x80000000)==0) x=t,y-=0x007e1;
    t=x+(x>>6); if((t&0x80000000)==0) x=t,y-=0x003f8;
    t=x+(x>>7); if((t&0x80000000)==0) x=t,y-=0x001fe;
    x=0x80000000-x;
    y-=x>>15;
    return y;
    }

    This code is for ln, so you will need a final multiplication

    log(x) = ln(x)*(1/ln(10)) = ln(x) * 0.434294


    Istvan
Sign In or Register to comment.