15

The C++ standard provides div(int, int), but not udiv(unsigned int, unsigned int).

If I naively used unsigned ints in this function, I can see that this would yield the wrong result for integers greater than 2^31 - 1 in the numerator. For example (with 4-bit nibbles):

The largest 4-bit nibble is 15, 1111 in binary. As a signed nibble, this would represent -1. Dividing 15 by 2 yields 7, or 0111, but dividing -1 by 2 yields 0: 0000.

Is there a straightforward way to adapt div to unsigned integers, or am I better off writing my own udiv, or avoiding the use of div and div-like functions altogether?

Edit/Note: In my case, I'm using unsigned long long ints, so using lldiv doesn't solve the problem.

castle-bravo
  • 1,389
  • 15
  • 34

2 Answers2

16

Back in the day, the result of / and % were not uniquely defined by C and div() was born. Now quotient from / is truncated towards 0.

unsigned math did not have this issue and so a lesser need for udiv().

Now many compilers recognize nearby a/b and a%b calculations and optimize quite well, reducing the need for even div(). Suggest just performing both calculations and let the compiler optimize it.


[Edit]
Detail: Prior to C99, division may truncate toward 0, toward INT_MIN or (maybe could round to nearest - I'll look into that). In any case % is the remainder after the division. div() was specified to only do one: divide with truncate toward 0. With C99, both div() and / perform a division with the quotient truncated toward 0.

See
What is purpose of the div() library function?
What is the behavior of integer division?

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Assuming you have an integer of n bytes, you can stocke k=2^n numbers, so if you have a negative number, getting its value as an unsigned would simply as adding k to it.

So what you could do is, test if the number is negatif, add k/q to the result.

However you could simply use the division operator /

x4rkz
  • 513
  • 4
  • 19