PDA

View Full Version : Convert 2 bytes of raw data to qint16

Smosia
23rd March 2014, 18:38
Hello.
Can you help me. I tried many methods to do that, but i didn't find solution.
I have 2 bytes of raw data (like that "45 FE"), stored in QByteArray (char 45, char FE). I want to convert them to qint16 (to decimal).
I have working solution (it's crazy:) ).

QByteArray buffer1;
qFromLittleEndian<qint16>((qint16)(buffer1.mid(i,1).at(0)))*256 + qFromLittleEndian<quint16>((const uchar *)buffer1.mid(i+1,1).constData());

Algoritm:
For numers > 0
converted first byte to signed qint16 * 256 + converted second byte to unsigned quint16.
For numbers < 0:
converted first byte to signed qint16 * 256 - converted second byte to unsigned quint16

256 = 100 in hex.

Could you recommend me right algorithm :) i think my algorithm is quite sophisticated :)

23rd March 2014, 19:05
quint16 res = *reinterpret_cast<const quint16 *>(&buffer1.constData[i]); // if you want 0xFE45

res = ((res << 8) | (res >> 8)); // if you want 0x45FE

ChrisW67
24th March 2014, 03:40
Slightly different approach. Different result if you use quint16 versus qint16, your initial post was unclear which you wanted:

QByteArray in("\x45\xfe", 2);
qint16 value1 = qFromLittleEndian<qint16>(reinterpret_cast<const unsigned char*>(in.constData()));
qDebug() << value1 << QString::number(value1, 16);
// -443 "fffffffffffffe45"
// ^^ The number is negative and has been sign extended to the size of a long.

quint16 value2 = qFromLittleEndian<quint16>(reinterpret_cast<const unsigned char*>(in.constData()));
qDebug() << value2 << QString::number(value2, 16);
// 65093 "fe45"

Smosia
24th March 2014, 14:04
Thank you, that was useful for me.
And if I will need to convert qint16 back to hex and add it back to QbyteArray. I can do something like that?

QByteArray buffer1;
qint16 buff = -443;
char * byte_buff= reinterpret_cast<char *>(&buff);
buffer1.append(*(byte_buff+1));
buffer1.append(*byte_buff);

ChrisW67
24th March 2014, 22:41
It never was hexadecimal to start with. You can use QString::number() as in my example, or QByteArray::toHex(), to display the value as a hexadecimal string.

To transfer the two bytes into a QByteArray in a little-endian byte ordering you could also use:

// No casting
qint16 value = -443; // OR quint16 value = 65093;
QByteArray out;
out.append(value & 0xFF);
out.append((value >> 8) & 0xFF);
qDebug() << out.toHex();

// OR
out.resize(sizeof(value)); // Must have the space already allocated
qToLittleEndian(value, reinterpret_cast<uchar *>(out.data()));
qDebug() << out.toHex();

You could do the original job without casting also:

QByteArray in("\x45\xfe", 2);
qint16 value = in.at(1) << 8 | in.at(0);
qDebug() << value << QString::number(value, 16);

Smosia
25th March 2014, 22:10
Thank you all. That was really helpful. Topic is closed :)