John Am John Am - 3 months ago 7
C Question

Multiply a long integer (32 bit ) with 0.0000000004656f in fixed point arithmetic

I'm trying to eliminate all floating point computations in an embedded application and I need to scale/multiply a signed long 32 bit integer with

0.0000000004656f
. (1/2147483648)

Can I replace this with fixed point multiplication?

The context is

( pulse[i] * ( triosc[i] * 0.0000000004656f ) )


Both
pulse[i]
and
triosc[i]
are signed long 32 bit integers

So I need my
triosc[i]
value to be constrained between
0.0f
and
1.0f
and this in fixed point arithmetic.

EDIT:

saw_x2[i] = (long)( pulse[i] * (triosc[i] * 0.0000000004656f) );
sine_osc[i] = (long)( ((triangle2[i] * (saw_x2[i] * 0.0000000004656f))) *
(pulse[i] * 0.0000000004656f) ) << 2;
return (sine_osc[i]);

Answer

Use this

 (((int_64t)pulse[i]) * triosc[i]) >> 31

The result will be a signed 32-bit integer, ranging from -1.0..0.9999... when interpreted as a fixed point number with the decimal point right after the sign bit. (Note the -1 interpretation. Another interpretation could be that INT_MIN is actually -0.)

The reason to cast to a larger datatype before multiplying is that otherwise you will lose accuracy. As your target size is exactly the input operands' sizes, you'd effectively lose everything.

Comments