Skip to main content
Konami
Senior
February 10, 2023
Question

How to round division on STM32G0

  • February 10, 2023
  • 4 replies
  • 2999 views

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.

This topic has been closed for replies.

4 replies

Chris21
Associate II
February 10, 2023

There are various ways to round numbers.

If you really want the remainder:

Remainder = Value % Divisor;

Konami
KonamiAuthor
Senior
February 10, 2023

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

Chris21
Associate II
February 10, 2023

For example, for positive values rounded up:

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

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

Tesla DeLorean
Guru
February 10, 2023

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 VenmoUp vote any posts that you find helpful, it shows what's working..
Konami
KonamiAuthor
Senior
February 10, 2023

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

Piranha
Principal III
February 12, 2023
#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".