cancel
Showing results for 
Search instead for 
Did you mean: 

How to round division on STM32G0

Konami
Senior II

I'm trying to implement an integer division with rounding. Obviously, by default integer division does floor and I was thinking I could use the remainder to determine if I should add 1 to my result.

Processor cycles are at a premium in this solution (running at 10s of kHz), so I'm seeking ways to do this with minimal overhead or ideally get the result "for free" as part of the existing division calculation

My question is, does anyone know of a good way of achieving this on the G0 which does not actually have a division instruction. Do I need to go into the disassembly and just see what it's doing? Do I need to write my own assembly code? Are there accepted solutions for this?

Note: Quotient and divisor are both arbitrary, and not constant integers.

7 REPLIES 7
Chris21
Senior

There are various ways to round numbers.

If you really want the remainder:

Remainder = Value % Divisor;

I'm sure there's an ARM library, or cook-book, of code examples, yielding the quotient and remainder

https://chromium.googlesource.com/chromiumos/platform/ec/+/stabilize-7077.134.B/core/cortex-m0/div.S

One obvious hack would be to multiply back out and subtract.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Konami
Senior II

Thanks, I'll take a look through the cook-book. I've edited my answer to note that processor cycles are very precious and I'm trying to optimize for minimal compute overhead. The calculation is running at 10s of kHZ

Added some more color to the question. Would love to hear some of the suggestions for ways to round

For example, for positive values rounded up:

Rounded = (Value + Divisor / 2) / Divisor;

If you can, it may be better to multiply instead of divide.

Piranha
Chief II
#define DIVU_CEIL(n, d)    ( ((n) + ((d) - 1)) / (d) )
#define DIVU_ROUND(n, d)    ( ((n) + (d) / 2) / (d) )
#define DIVS_ROUND(n, d)    ( (((n) < 0) ^ ((d) < 0)) ? (((n) - (d) / 2) / (d)) : (((n) + (d) / 2) / (d)) )

The 4th character in the macro name means "unsigned/signed". Also watch out for overflows on addition/subtraction to/from the "n".

It's not "up" but instead is "to nearest" - the normal mathematical rounding.