This is a 16 bit unsigned value that the caller task assigns while sending a message. For each new message the value increments by one, eventually wrapping round and producing a sequence 0,1,2,……65533,65534,65535,0 etc. So I need a counter to find targets. I need help in getting the most efficient way to wrap around. For example if the current value is 65534 and my target count is 5, I need a function to wrap around and set the target to the correct value.
Asked
Active
Viewed 3,010 times
3 Answers
2
If you are using an unsigned int
counter then you can simply do (x + 5) & 0xffffU
- there is no need to check for overflow because arithmetic in unsigned types is defined to wrap around in C, and unsigned types must use a pure binary representation.

caf
- 233,326
- 40
- 323
- 462
0
If your computer supports uint16_t
(defined in <stdint.h>
in C99 and C11 compilers), then use that.
uint16_t v = 65534;
v += 5;
assert(v == 3);
If your computer does not support uint16_t
, then you can use:
unsigned int v = 65534;
v = (v + 5) & 0xFFFF;
assert(v == 3);

Jonathan Leffler
- 730,956
- 141
- 904
- 1,278
-
1[This answer](http://stackoverflow.com/a/19843181/2327831) says that is undefined behavior since `v` is promoted to `signed int` here `v += 5;`, and overflow on signed is undefined. Am I missing something? ( Maybe `v = ( unsigned int )v + 5u` would be correct? ) – this Nov 28 '13 at 04:15
-
If a compiler broke this, I'd refuse to use the compiler. There are two possibilities worth discussing, assuming CHAR_BIT is 8. Case (1): `sizeof(int) == 2`; then 65534 is an `unsigned int` and the behaviour is defined. Case (2): `sizeof(int)` is bigger than 2, so 65534+5 won't overflow, so the conversion back to `uint16_t` is safe. – Jonathan Leffler Nov 28 '13 at 04:16
-
Case(2): `65534+INTMAX_MAX` will overflow. `+5` was never limited by anything so it might as well be max int. – this Nov 28 '13 at 04:25
-
It's meant to be 16-bit arithmetic; the increment should be limited to 65535. – Jonathan Leffler Nov 28 '13 at 04:29
-
-
The code discusses primarily incrementing by one per message. If you're worried about large values of increment, you can mask that before adding. It feels like you are quibbling about nothing. I don't plan to respond again. – Jonathan Leffler Nov 28 '13 at 04:36
-
That's ok, I didn't mean to antagonize you. I was just curious and i think details are important when it comes to such things. – this Nov 28 '13 at 04:40
-2
If it increments only by one, you can simply do the following:
#include <limits.h>
if (myint == (INT16_MAX - 1))
counter++;
myint++;
However, the "correct" way to do it which will always detect overflow is as follows:
#include <limits.h>
if ((INT16_MAX - myint) < numtoadd)
counter++;
myint += numtoadd;

IllusiveBrian
- 3,105
- 2
- 14
- 17
-
2
-
This answer is a lot more complicated than it needs to be, since OP is working with unsigned values. caf's answer is better. – R.. GitHub STOP HELPING ICE Nov 28 '13 at 04:07