2018-04-03 04:50 PM
For example, if I have:
unsigned long int Variable1;
Variable1 = 0xFFFFFFFF;
Variable1++;
What would be the value of Variable1? Would it be back to zero?
Thanks.
Note: this post was migrated and contained many threaded conversations, some content may be missing.2018-04-03 04:53 PM
Yes, and it would set the overflow flag.
also it would become positive not negative.
2018-04-03 06:22 PM
32-bit math on the CM0 same as CM3/4, etc
2018-04-04 12:00 AM
If this is written in C, then this behaviour (somewhat surprisingly) follows from the language not the processor, see C99 6.2.5#9:
A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
Quoting the explanation by Derek Jones:
This behavior describes what most processor operations on unsigned values already do. In those rare cases
where a processor does not support unsigned operations, calls to internal library functions have to be made.In your particular case, the result depends on definition of unsigned long int - although probably all existing Cortex-M-targeting compilers define it as 32-bit; a compiler may quite well chose it to be other than 32-bit, and then it would not overflow at this particular case.
JW
2018-04-05 03:17 PM
Assuming a non-buggy C-compliant compiler, yes.
2018-04-05 04:48 PM
I've tested it using Keil and STM32F042 device and the Variable1 goes back to zero. I guess I just want to be sure it is a known and defined operation, not something that can have a random result.
Also, if I have two long unsigned int variables and if I perform subtraction, I would do something like this:
unsigned long int var1, var2;
int result;
result = (int)(var1 - var2);
result would be negative if var2 > var1, and positive if var1 > var2.
2018-04-06 12:48 AM
Even if unsigned long int would be of the same width as int (i.e. both 32-bit in the CortexM world), this can't be guaranteed.
For example, if var1 = 0xFFFFFFFF = +4294967295 and var2 = 0, as var1>var2 you expect the result to be positive, but with probably all compilers the result will be 0xFFFFFFFF which interpreted as int is -1.
JW
2018-04-11 09:45 AM
Ah ... you're right, but I forgot to mention that since I am only interested in unsigned
arithmetic only, my actual codes are like below:
result = abs((int) (var1 - var2));
so abs ( (int)(0xFFFFFFFF - 0) ) = 1 which is the intended result.
but that was good point.
Thanks.
2018-04-11 09:52 AM
I guess I should explain why I brought this up in the first place. I need to use a variable to keep track of elapsed time.
I have a 0.5 seconds timer that counts up a variable in this case I use an 'unsigned long int'. Because of potential
overflow, I want to make sure the arithmetic is correct in case of overflow. All I need is the increment count, not the
actual sign. That is why I use abs().
2018-04-11 10:31 AM
The abs is unnecessary here, for
volatile uint32_t uwTick.
uint32_t Start;
Start = uwTick;
while((uwTick - Start) < 500); // Works for all values in the uint32_t number space
with abs() you'll fail beyond 0x7FFFFFFF ticks