unsigned long
Тип unsigned long хранит 32-битное целое без знака (0–4 294 967 295) и незаменим при работе с millis(), micros() и большими счётчиками.
Полная статья
Описание
unsigned long — это 32-битный целочисленный тип данных (4 байта), который хранит только неотрицательные числа: от 0 до 4 294 967 295 (2³² − 1). В отличие от long, у которого половина диапазона уходит на отрицательные значения, unsigned long отдаёт весь диапазон под положительные числа.
Чаще всего этот тип используют для хранения значений функции millis() и micros(), которые возвращают время работы программы в миллисекундах и микросекундах соответственно. Эти функции сами возвращают unsigned long, поэтому переменная того же типа — правильный выбор для работы с ними.
Синтаксис
unsigned long var = val;
Параметры
var: имя переменнойval: начальное значение, присваиваемое переменной (необязательно при объявлении, но рекомендуется)
Пример кода
unsigned long time;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Time: ");
time = millis();
//выводит время с момента запуска программы
Serial.println(time);
// пауза в одну секунду, чтобы не отправлять слишком много данных
delay(1000);
}
Где применяется
- Отсчёт времени — хранение результата
millis()илиmicros()для измерения интервалов без блокировки программы. - Счётчики событий — подсчёт импульсов, оборотов или других событий, количество которых может превысить 65 535 (предел
unsigned int). - Работа с большими числами — вычисления, в которых промежуточный результат выходит за пределы
intилиunsigned int, но заведомо неотрицателен. - Протоколы связи — хранение меток времени или идентификаторов пакетов, которые передаются как 32-битные беззнаковые значения.
Практические замечания
- Переполнение работает предсказуемо. Если значение
unsigned longдостигает 4 294 967 295 и увеличивается на 1, оно обнуляется и продолжает счёт с 0. Именно так ведёт себяmillis()примерно через 49 дней непрерывной работы. Чтобы корректно измерять интервалы даже при переполнении, вычитайте старое значение из нового:unsigned long elapsed = currentMillis - previousMillis;— арифметика беззнаковых чисел даст правильный результат. - Не смешивайте со знаковыми типами. Если вы присвоите
unsigned longотрицательное число или сравните его с отрицательной константой, компилятор может выдать предупреждение, а результат окажется неожиданным. Например,-1вunsigned longпревратится в 4 294 967 295. - Литералы больших чисел лучше записывать с суффиксом
UL, чтобы явно указать компилятору тип:unsigned long x = 3000000000UL;. - На большинстве плат Arduino (Uno, Nano, Mega)
unsigned longиunsigned intзанимают разный объём:unsigned int— 2 байта (до 65 535),unsigned long— 4 байта. На платах с 32-битным процессором (Due, Zero)unsigned intуже 4 байта, ноunsigned longостаётся 4-байтным. - При выводе через
Serial.print()значениеunsigned longотображается корректно без дополнительных преобразований.