# Arduino 60 \* 1000 gives a strange number: integer constants overflow

> Fix long time calculations: constants are int by default, so write 60UL \* 1000 to avoid overflow on a 16-bit board.

Canonical: https://roboticsengineering.in/fix/arduino-60-times-1000-overflow-use-ul-suffix/ | Published: 2026-11-03 | Updated: 2026-11-04

**Add UL to at least one number: 60UL \* 1000.** On an Uno an int holds up to 32767 only.

## What the message means

The compiler calculates with the type of the constants. Two plain ints overflow before the result is stored in a larger variable.

## Fix it in this order

1. Write one constant as unsigned long, such as 60UL or 1000UL.
2. Declare the variable as unsigned long.
3. Check intermediate results, since a big product overflows before the next division.
4. Print the value to confirm it.
5. On 32-bit boards such as the ESP32 the problem is much rarer.

## Why it happens

On an Uno an int is 16 bits and holds at most 32767. The expression 60 \* 1000 is calculated as ints, so it overflows and gives a wrong number before it is stored in a larger variable.

Add the UL suffix so the maths uses unsigned long, for example 60000UL or 60UL \* 1000.

## If you see this, do this

| You see | Do this |
| --- | --- |
| Interval is too short or negative | Overflow. Add UL. |
| Works on ESP32, fails on Uno | int size. |

## Related

[int overflow](https://roboticsengineering.in/fix/arduino-int-overflow-wrong-calculation/), [millis timing](https://roboticsengineering.in/fix/arduino-millis-timer-overflow-use-unsigned-long/).

Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.

## Why this happens

The C++ compiler picks the type of an arithmetic expression from the types of its operands, not from the variable that will receive the result. In 60 \* 1000 both numbers are plain int constants, so the multiplication is done in int. On an Uno (ATmega328P) an int is 16 bits, signed, with a range of -32768 to 32767. The true answer, 60000, does not fit.

The result wraps around. 60000 minus 65536 is -5536, so the expression typically holds -5536. When that value is then stored into an unsigned long, it is converted to a huge positive number (4294961760). Declaring the variable as unsigned long is therefore not enough; the overflow has already happened inside the expression. The UL suffix makes one operand unsigned long, and the whole multiplication is then done in 32 bits.

## How to confirm the cause

- Print the size of an int: Serial.println(sizeof(int)). A result of 2 means 16-bit ints (Uno, Nano, Mega); 4 means a 32-bit board such as the ESP32.
- Print the suspicious expression itself, not only the variable. If you see -5536 or 4294961760 for 60 \* 1000, the overflow is in the constants.
- Read the compiler output. avr-gcc often prints a warning such as ‘integer overflow in expression’ for constant products; turn on warnings in the IDE preferences if you do not see it.
- Split a long formula into steps and print each step. The first step that gives a negative or odd number is where the overflow starts.

## Worked example

This sketch shows both results on an Uno.

```
unsigned long wrong = 60 * 1000;     // int * int, wraps first
unsigned long right = 60UL * 1000;   // unsigned long maths

void setup() {
  Serial.begin(9600);
  Serial.println(wrong);   // 4294961760 on an Uno
  Serial.println(right);   // 60000
}
void loop() {}
```

## Common mistakes

- Assuming the variable type fixes the maths. The type on the left of = does not change how the right side is calculated.
- Writing the suffix on a result, not an operand. (60 \* 1000)UL is not valid; put UL on 60 or 1000.
- Using plain int for time values. One minute in milliseconds, 60000, already does not fit; a day, 86,400,000, needs unsigned long.
- Fixing only the last multiplication in a long chain such as 24 \* 60 \* 60 \* 1000. Put UL on the first number so every step is unsigned long.

## If this did not fix it

- Check the millis() comparison. Subtract the stored time from millis() (millis() – last >= interval) rather than comparing against a sum that might overflow.
- Check other 16-bit limits: analogRead values multiplied by a large factor, or map() results, can overflow in the same way.
- Check that the interval variable itself is unsigned long and not int or long.
