unsigned int

Описание

На UNO и других платах на базе ATMEGA беззнаковые целые числа (unsigned int) аналогичны int в том, что они хранят 2-байтовое значение. Однако вместо хранения отрицательных чисел они хранят только положительные значения, что даёт полезный диапазон от 0 до 65 535 ((2^16) - 1).

На плате Due хранится 4-байтовое (32-битное) значение в диапазоне от 0 до 4 294 967 295 (2^32 - 1).

Разница между беззнаковыми (unsigned) и знаковыми (signed) целыми числами заключается в том, как интерпретируется старший бит, иногда называемый битом «знака». В типе Arduino int (который является знаковым), если старший бит равен «1», число интерпретируется как отрицательное, а остальные 15 бит интерпретируются с использованием дополнительного кода.

Синтаксис

unsigned int var = val;

Параметры

  • var: имя переменной

  • val: значение, которое вы присваиваете этой переменной

Пример кода

unsigned int ledPin = 13;

Примечания и предупреждения

Когда беззнаковые переменные превышают свою максимальную ёмкость, они «переполняются» обратно в 0, и наоборот:

unsigned int x;
x = 0;
x = x - 1;  // x теперь содержит 65535 — переполнение в отрицательном направлении
x = x + 1;  // x теперь содержит 0 — переполнение

Математические операции с беззнаковыми переменными могут давать неожиданные результаты, даже если ваша беззнаковая переменная никогда не переполняется.

Микроконтроллер применяет следующие правила:

Вычисление выполняется в контексте переменной назначения. Например, если переменная назначения знаковая, будет выполняться знаковая арифметика, даже если обе входные переменные беззнаковые.

Однако при вычислении, которое требует промежуточного результата, контекст промежуточного результата не определён кодом. В этом случае микроконтроллер выполнит беззнаковую арифметику для промежуточного результата, поскольку оба входа беззнаковые!

unsigned int x = 5;
unsigned int y = 10;
int result;

result = x - y; // 5 - 10 = -5, как и ожидалось
result = (x - y) / 2; // 5 - 10 в беззнаковой арифметике — это 65530!  65530/2 = 32765

// решение: используйте знаковые переменные или выполняйте вычисление пошагово.
result = x - y; // 5 - 10 = -5, как и ожидалось
result = result / 2;  //  -5/2 = -2 (только целочисленная арифметика, дробная часть отбрасывается)

Зачем вообще использовать беззнаковые переменные?

  • Желательно поведение при переполнении, например, для счётчиков

  • Знаковая переменная немного мала, но вы хотите избежать потери памяти и скорости при использовании long/float.

Смотрите также