a small math demo
Reinhard
Posts: 489
Hi , today I make a small experiment using the propeller log table, how descibed in the propeller manual page 420 ff.
It's calculate a cubic root without math library.
Thats not the fastest ( in my C - implementation) but a good exercise for me.
It's calculate a cubic root without math library.
Thats not the fastest ( in my C - implementation) but a good exercise for me.
/* propeller-elf-gcc -mlmm -o log2.elf log2.c */ #include <stdio.h> #ifdef __PROPELLER__ #include <propeller.h> #endif //#define DEBUG_LOG2 int time_clocks() { #if defined(__propeller__) return (CNT); #else return 0; #endif } unsigned short findLeadingBitPosition(unsigned aNumber) { short pos; if(aNumber == 0) return 0; for(pos = 31; pos >= 0; pos--) { if( aNumber & (1 << pos)) { return (unsigned short)pos; } } } int errUnsignedToBase2Exponent( unsigned num , unsigned * exponent) { unsigned short bitpos,tmp2,index,exp=0; unsigned tmp,remainder; int shift; if(num <= 0 ) { // underflow *exponent = ~2; return -2; } if(num >= 0x80000000) { // overflow *exponent = ~1; return -1; } bitpos = findLeadingBitPosition(num); #ifdef DEBUG_LOG2 printf("bitpos: 0x%X %d\n",bitpos,bitpos); #endif tmp2 = bitpos; tmp = 1 << bitpos; #ifdef DEBUG_LOG2 printf("tmp: 0x%X %d\n",tmp,tmp); #endif remainder = num - tmp; #ifdef DEBUG_LOG2 printf("remainder: 0x%X %d\n",remainder,remainder); #endif if(remainder <= 0x0F) { index = remainder << 8; } else if(remainder <= 0xFF) { index = remainder << 4; } else if(remainder <= 0xFFF) { index = remainder; } else { for(shift = 11; shift >= 0; shift--) { bitpos --; if(remainder & (1<<bitpos)) { index |= (1 << shift); } } } index &= 0xFFF; index += 0xC000; #ifdef DEBUG_LOG2 printf("index: 0x%X %d\n",index,index); #endif #ifdef __PROPELLER__ exp = *( unsigned short *)(index); #endif #ifdef DEBUG_LOG2 printf("exp: 0x%X\n",exp); #endif *exponent = (tmp2<<16) | exp; return 0; } int main(int argc, char *argv[]) { unsigned num[] = {0x60000000,2048,2047,2049,0x1FFF,0x40,2,4,8,17,0,0x80000000}; unsigned n,n1,n2,exp,exp1,exp2; int err,i; int start, end; for(i=0; i < sizeof(num)/sizeof(unsigned); i++) { start= time_clocks(); err = errUnsignedToBase2Exponent( num[i] , &exp); end = time_clocks(); printf("Error=%02d\tnumber=0x%08X\tBase2Exponent=0x%08X\t\tclocks:%d\n",err,num[i],exp,end-start); } printf("\n\n------------------------- cube root demo ---------------------\n"); n1 = 2048; err = errUnsignedToBase2Exponent( n1 , &exp1); exp2 = exp1/3; printf("Error=%02d\tnumber=0x%08X\tBase2Exponent=0x%08X\t0x%08X\n",err,n1,exp1,exp2); printf("exact: 2048 ^ (1/3) = 12.699208\n"); printf("result: %X integer part = %X fractional part = %X\n",exp2,(exp2&0xFF0000)>>16,exp2&0xFFFF); printf("means: 2 ^ ( 3 + 1/2 + 1/8 + 1/32 + 1/128 .... + 1/32768) = 12.699118\n"); return 0; }
Comments
I have a some questions.
- Is there any particular reason you chose to surround #include <propeller.h> with an #ifdef ?
- Why didn't you just use the ANSI C library clock() function for time_clocks() ?
Thanks for your continuing efforts. Please PM me if you need extra support.--Steve
Thank you Steve.
1. the reason is I wrote first the program with devcpp on personal computer, for debugging the flow logic.
In this case I get errors if including <propeller.h>, and runtime error on pointer access to memory location.
If I see that programm works, so I use this C - file without changes and compile with propeller-gcc.
2. I forgot, this ANSI C library function, Thanks for remember me !
best regards,
Reinhard