Неожиданные результаты при создании 32-битного целого числа из массива байтов
У меня возникли проблемы с созданием 32-битного целого числа из 4-байтового массива. В следующем полном, минимальном и проверяемом примере преобразование массива байтов, содержащего 0x00, 0x04, 0x04F, 0x45
, приводит к 4F45
(ожидаемый результат будет 44F45
). Должно быть, я упускаю из виду что-то фундаментальное... Кто-нибудь может увидеть, где я ошибся?
void setup()
{
Serial.begin(9600);
while(!Serial);
}
void loop()
{
uint8_t bytes[4] = {0x00, 0x04, 0x4F, 0x45}; //00044F45
int32_t theInt = byteArrayToInt32(bytes);
Serial.println(theInt, HEX); // Печать 4F45
delay(250);
}
uint32_t byteArrayToInt32(uint8_t* bytes)
{
uint32_t i = 0;
i |= bytes[0] << 24;
i |= bytes[1] << 16;
i |= bytes[2] << 8;
i |= bytes[3];
return i;
}
1 ответ
Лучший ответ:
Проблема в том, что вы пытаетесь сдвинуть uint8_t
более чем на 8 бит, а затем выполняете ИЛИ
с помощью int32_t
.
Вы должны преобразовать
uint8_t
в int32_t
перед выполнением сдвига.
void setup()
{
Serial.begin(9600);
while(!Serial);
}
void loop()
{
uint8_t bytes[4] = { 0x00, 0x04, 0x4F, 0x45}; //00044F45
int32_t theInt = byteArrayToInt32(bytes);
Serial.println(theInt, HEX); // Печать 4F45
delay(1000);
}
int32_t byteArrayToInt32(uint8_t* bytes)
{
int32_t i = 0;
i |= (int32_t) bytes[0] << 24;
i |= (int32_t) bytes[1] << 16;
i |= (int32_t) bytes[2] << 8;
i |= (int32_t) bytes[3];
return i;
}
Обратите внимание, что если старший бит bytes[0]
установлен, то (int32_t) bytes[0] << 24
сдвинет его на знаковый бит, что является неопределенным поведением. Безопаснее приводить к uint32_t
, который, в свою очередь, можно безопасно присвоить int32_t
., @Edgar Bonet
Хм, то, как вы предложили, решает проблему, однако я очень озадачен тем, почему сдвиг влево на 8 бит работал изначально?, @You'reAGitForNotUsingGit
похоже, что функция сдвига влево использует 16-битный буфер .... возможно, потому, что он использует тот же код для 16-битных сдвигов, @jsotola
- Есть ли ограничения на размер массива в Arduino Mega 2560?
- Int64_t, он же long long, действует как int32_t и переполняется на 2^31.
- Определить, имеет ли переменная арифметический тип
- Каковы размеры каждого примитивного типа данных в SAMD51 Metro M4 Express?
- Преобразование строки в целое число
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Как получить тип данных переменной?
@jsotola каким образом?, @You'reAGitForNotUsingGit
@jsotola Я повторно протестировал его как
uint32_t
, без разницы :(, @You'reAGitForNotUsingGit