0

Sorry for the wordy title. My code is targeting a microcontroller (msp430) with no floating point unit, but this should apply to any similar MCU.

If I am multiplying a large runtime variable with what would normally be considered a floating point decimal number (1.8), is this still treated like floating point math by the MCU or compiler?

My simplified code is:

int multip = 0xf;          // Can be from 0-15, not available at compile time
int holder = multip * 625; // 0 - 9375
holder = holder * 1.8;     // 0 - 16875`

Since the result will always be a positive full, real integer number, is it still floating point math as far as the MCU or compiler are concerned, or is it fixed point?

(I realize I could just multiply by 18, but that would require declaring a 32bit long instead of a 16 bit int then dividing and downcasting for the array it will be put in, trying to skimp on memory here)

cde
  • 317
  • 1
  • 18

4 Answers4

2

If you write a floating-point multiply, I know of no compiler that will determine that there's a way to do that in fixed-point instead. (That does not mean they do not exist, but it ... seems unlikely.)

I assume you simplified away something important, because it seems like you could just do:

result = multip * 1125;

and get the final result directly.

I'd go for chux's formula if there's some reason you can't just multiply by 1125.

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775
2

The result is not an integer; it rounds to an integer.

9375 * 1.8000000000000000444089209850062616169452667236328125

yields

16875.0000000000004163336342344337026588618755340576171875

which rounds (in double precision floating point) to 16875.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • That's because the compiler or mcu inherently treats 1.8 as a float, immediately creating imprecision right? Shame. Thanks. – cde Sep 18 '13 at 02:29
  • You could always do the calculation as `holder *= 2; holder -= holder/10;` – R.. GitHub STOP HELPING ICE Sep 18 '13 at 03:06
  • @cde Not the MCU, but the compiler treats 1.8 as a float. The MCU is stupid that it just executes the instructions in the hex file(output of the linker). So it's the compiler that optimizes the floating point operations. –  Sep 18 '13 at 04:55
0

Confident FP code will be created for

holder = holder * 1.8

To avoid FP and 32-bit math, given the OP values of

int multip = 0xf;    // Max 15
unsigned holder = multip * 625; // Max 9375
// holder = holder * 1.8; 
// alpha depends on rounding desired,  e.g. 2 for round to nearest.
holder += (holder*4u + alpha)/5;
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

If int x is non-negative, you can compute x *= 1.8 rounded to nearest using only int arithmetic, without overflow unless the final result overflows, with:

x - (x+2)/5 + x

For truncation instead of round-to-nearest, use:

x - (x+4)/5 + x

If x may be negative, some additional work is needed.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312