 # Millis() with int

I am using this code to print out on a serial monitor at a particular interval. I don't understand why the code works in the -ve values.

millis() gives unsigned long, however, I am curious why the if statement works in the -ve values.

``````int ct, pt = 0;

void setup() {
Serial.begin(115200);
}

void loop() {
ct = millis();
if (ct - pt > 1000) {
Serial.print("ct: ");
Serial.print(ct);
Serial.print("\tpt: ");

Serial.println(pt);
pt = ct;
}
}
``````

The output is in the image.
ct - current time
pt - previous time because the code has not exceeded the limits of an int, yet.

if ct = -31908 and pt = 32627 is considered. The if statement

``````if (ct - pt > 1000)
``````

still works. Why?

(-31908)-32627= 719 is a legitimate math problem that does not exceeded the limits of the declared variables. An int is both + and - a unsigned int is intended for positive numbers only.

What problem are you having with the numbers?

You can make yourself a "tiny millis timestamp" that can handle overflow just like its 'unsigned long' brother. Example:

``````unsigned int littleNow = millis()
``````

subsequently, you can safely do things like:

``````unsigned int lastLittleNow;
...
if (littleNow - lastLittleNow >= interval) { ...
``````

with the restriction than 'interval' can be no longer than 65535ms

To see how (-31908) - (32627) works in 16 bits we first convert the numbers to hexadecimal:
0x835C - 0x7F73
We change that to an addition problem by changing it to:
0x835C + (-0x7F73)
To negate 0x7F73 we invert the bits and add 1 (2's Complement)
0x835C + 0x808D
The result of the addition is: 0x103E9 (66537) but that gets truncated to 16 bits so the actual result is:
0x03E9 = 1001 which is greater than 1000.

2 Likes