Почему в C ++ big endian в int16 с битовым сдвигом не работает? - PullRequest
1 голос
/ 07 мая 2020

Я читаю байтовый массив (2 байта с прямым порядком байтов) с Qt

QByteArray a = data.mid(cellNumber, 2);
int16 res = qFromBigEndian<qint16>(a);

и хочу получить int16. Он работает правильно, но медленно.

Если я использую

std::bitset<16> b0(a[0]);
std::bitset<16> b1(a[1]);
qint16 b = (b0 << 8) | (b1 << 0);

, результат будет неверным. Причина следующая:

00000001 a0
10101011 a1

00000000 00000001 b0 correct
11111111 10101011 b1 not correct, why does it fill with 1? (should be 00000000 10101011)
-----------------
11111111 10101011 wrong!
00000001 10101011 this would be correct

Кто-нибудь знает, что я делаю не так?

Ответы [ 2 ]

1 голос
/ 07 мая 2020

bitset возьмите unsigned long long, тогда как QByteArray::operator[] верните char, signed в вашем случае.

И у вас есть интегральное продвижение, делая отрицательное число как большое число (заполненное 1).

Возможное решение

std::bitset<16> b0(static_cast<unsigned char>(a[0]));
std::bitset<16> b1(static_cast<unsigned char>(a[1]));
0 голосов
/ 07 мая 2020

Спасибо всем !!!

std::bitset<16> b0(static_cast<unsigned char>(a[cellNumber]));
std::bitset<16> b1(static_cast<unsigned char>(a[cellNumber + 1]));
std::bitset<16> resb = (b0 << 8) | (b1 << 0);
int16_t resi = int16_t(resb.to_ulong());

Я тестировал его также на отрицательные значения, если они, конечно, не превышают пределы int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...