Odd request... Anybody have log10 in spin?
Stephen Moraco
Posts: 321
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...
So, does anybody know of a spin-only version I can "leverage"?
Stephen, KZ0Q
--
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...
So, does anybody know of a spin-only version I can "leverage"?
Stephen, KZ0Q
--
Comments
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.
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
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