uint32_t a = 0xFF << 8;
uint32_t b = 0xFF;
uint32_t c = b << 8;
Я компилирую для Uno (1.0.x и 1.5), и было бы очевидно, что "a" и "c" должны быть одинаковыми, но они не... по крайней мере, не при запуске на цель. Я компилирую тот же код на хосте и не имею никаких проблем.
Правая смена работает нормально, сдвиг влево работает только тогда, когда я изменяю переменную в сравнении с константой.
Может ли кто-нибудь подтвердить это?
Я использую Visual Micro с VS2013. Компиляция с результатом 1.0.x или 1.5 arduino приводит к тому же отказу.
[РЕДАКТИРОВАТЬ]
На цель: A = 0xFFFFFF00 C = 0x0000FF00
Проблема связана с подписанным/неподписанным неявным литьем.
С uint32_t a = 0xFF << 8;
ты имеешь в виду
0xFF
; это signed char
;0xFFFFFFFF
;a = 0xFFFFFF00
.Если вы хотите воспроизвести одно и то же поведение, попробуйте этот код:
uint32_t a = 0xFF << 8;
uint32_t b = (signed char)0xFF;
uint32_t c = b << 8;
Serial.println(a, HEX);
Serial.println(b, HEX);
Serial.println(c, HEX);
В результате
FFFFFF00
FFFFFFFF
FFFFFF00
Или, наоборот, если вы пишете
uint32_t a = (unsigned)0xFF << 8;
вы получите, что a = 0x0000FF00
.
В компиляторе есть только две странные вещи:
uint32_t a = (unsigned char)0xFF << 8;
возвращает a = 0xFFFFFF00uint32_t a = 0x000000FF << 8;
возвращает a = 0xFFFFFF00.Возможно, это неправильный перевод в компиляторе....
int
без signed char
. Целочисленные литералы должны быть int
, long int
или long long int
. Поскольку int имеет ширину 16 бит в Arduino, 0xFF << 8 будет отрицательным. Поэтому результат будет 0xFFFFFF00
вместо 0xFFFFFFFF. Только после приведения к (signed char)0xFF
оно станет 0xFFFFFFFF. Даже «странные вещи» выше тоже правильно. Просто вы не знаете как стандарт C, так и компилятор.
[Кредит идет Мацу Петерсону]
Использование оператора трансляции, чтобы заставить компилятор обрабатывать 0xFF как uint32_t, решает проблему. Похоже, что Arduino xcompiler рассматривает константы немного по-другому, так как я никогда не делал их перед сменой.
Благодарю!
b
присваивается 32-битное значение при присваивании, поэтому, когда вы сдвигаете его влево позже, не возникает вопроса о переполнении. Если число умалчиваемого размера был 8 бит , то назначение переполнится.a