Signed and unsigned numbers
What do signed and unsigned mean? In computer terms they refer to integer values. That is, a value with no fractional part. For example:
An unsigned integer can represent values 0 and higher.
A signed integer value respresents values negative and positive (and zero).
In C/C++ variales are limited as the magnitude of the numbers that can be represented in variables of a given size. Check out the binary hints and tips for how numbers are represented.
It overflows and wraps around to 0. Internally the cpu will generate a carry status when performing this arithmetic indicating the overflow. If we were programming in assembler (machine language) we would have access to the carry status bit. However in C/C++ (and most other high level languages) we don't have direct access to the cpu status bits, including carry).
If you are writing software to control a rocket and use a 16 bits to represent the rocket's speed, you better be VERY sure the rocket won't ever go faster than 65535 mph because if it goes 1 mph faster, the value will wrap/roll over to 0, probably causing all the navigational computations to go haywire sending the rocket the wrong way. Oops....
Back to signed values. How in tarnation does a computer represent negative numbers?
The answer is something called two's complement arithmetic.
Suppose a 4 bit variable has a value of 1111 and you add 1 to it. It wraps around with a result of 0000.
What happens if you have a value of 0000 and subtract 1 from it? In unsigned arithmetic the answer is 1111. Another type of carry occured - in grade school when the teach subtraction this is called a borrow. And yes, the cpu's internal carry bit would be set by this subtraction.
What if we set (roughly) half of the values that can be represented aside to be negative numbers?
Any signed value where the msb (most significant bit) is '1' is considered NEGATIVE.
binary decimal ------ ------- 0111 7 0110 6 0101 5 0100 4 0011 3 0010 2 0001 1 0000 0 1111 -1 1110 -2 1101 -3 1100 -4 1011 -5 1010 -6 1001 -7 1000 -8
A two's complement value of width bits can represent integer values from 2(width-1)-1 to -2(width-1)
With unsigned values wrapping around returns us to 0. With signed values we wrap around to the most negative number. This can result in unexpected behavior. Let's look at an example involving a microsecond timer.
long timeval; // signed 32 bit variable long testtime; // signed 32 bit variable timevalue = micros(); // get the current microsecond count if (timevalue < testtime) { ... }
This will behave as expected until micros() (which is declared to return an unsigned long value) returns a number larger than 2,147,483,647. Because timevalue number is a signed variable, its value is interpreted as a negative number!
As Robin might have observed to Batman, "Holy intermittent failures, Batman!" Or perhaps not so intermittant, after roughly 2147 seconds of operation (or 36 minutes) things will likely go seriously wrong. So be sure, when testing your programs to run them for more than 36 minutes!
One more thing about micros() and millis() returning unsigned 32 bit values. Remember the code where we're looking to see if the period since a save start time has exceeded a specified duration (look in bcsjTimer.cpp)?
unsigned long starttime; unsigned long duration; if (micros() - starttime > duration) { // our time period has elapsed }
What happens if micros() (or millis()) wraps around after starttime is saved? Don't we get a negative number?
Let's use our trivial 4 bit arithmetic to mmake this easier to understand...
Let micros() return 1 (binary 0001) Let starttime be 13 (binary 1101) ------ subtracting we get 0100
Which is the expected duration of 4 microseconds since starttime. 13, 14, 15, 0, 1
Using unsigned numbers our duration computation works even if micros() wraps around to what wiould seem to be a time previous to starttime!
This works as long as the duration is less than half the resolution of variables! So keep those microsecond time values under 36 minutes and you should be OK!
Would this work if starttime and duration were signed values? Why or why not?
Neat!
To sum up:
This page and files copyright © 2016 by Charlie Comstock.