> cchandel wrote:
> Hi,
>  I wrote guitartuner a while ago - and found that the large number of
> floating point operations were a major bottleneck.
>  Can anyone point me to an opensource implementation of int based floating
> point calculations that I could use without any licensing issues for
> development on the FR?
I don't have a floating point library, but the following fixed point
code should be (approximately) right:

enum unsigned_fixed_special_values
{
        underflow : 65533,
        overflow : 65534,
        invalid : 65535,
        
        low_mask : 255,
        high_mask : 65280,
        
        high_offset : 256
};

unsigned unsigned_fixed_add( unsigned a, unsigned b )
{
        unsigned r;
        
        r = a + b;
        
        if( r >= underflow )
        {
                r = overflow;
        }
        
        return( r );
}

unsigned unsigned_fixed_sub( unsigned a, unsigned b )
{
        if( b < a )
        {
                return( underflow );
        } else {
                return( a + b );
        }
}

int unsigned_fixed_mul( unsigned num, unsigned den )
{
        unsigned den_a, den_b, tmp;
        
        den_b = ( den & high_mask ) / high_offset;
        
        if( ( num & high_mask ) / high_offset * ( den_b ) > low_mask )
        {
                return( overflow );
        }
        
        den_a = den & low_mask;
        
        tmp = ( num * den_b ) + ( num / den_a );
        
        if( tmp >= high_mask | low_mask )
        {
                tmp = overflow;
        }
        
        return( tmp );
}

unsigned unsigned_fixed_div( unsigned num, unsigned den )
{
        unsigned den_a, den_b, tmp;
        
        if( den & ( low_mask & high_mask ) == 0 )
        {
                return( invalid );
        }
        
        den_a = den & low_mask;
        
        if( ( num & high_mask ) / high_offset * ( den_a ) > low_mask )
        {
                return( overflow );
        }
        
        den_b = ( den & high_mask ) / high_offset;
        
        tmp = ( num * den_a ) + ( num / den_b );
        
        if( tmp >= high_mask | low_mask )
        {
                tmp = overflow;
        }
        
        return( tmp );
}

Beware that it hasn't been tested. It only does unsigned, but it can
handle signed with some simple wrapper functions. Also, I write in
C++, so I don't know how long names are allowed to be in C. I don't
remember whether enums are allowed to be accessed like that (I deal
with those things when compiling, not coding).

This code is for 16-bit floating point. Adjust it as needed. I didn't
try for underflow checking on the multiply/divide functions.

_______________________________________________
devel mailing list
devel@lists.openmoko.org
https://lists.openmoko.org/mailman/listinfo/devel

Reply via email to