Problem with number types - convert binary QString to decimal
linux - Qt 4.8.2
Hello,
I'm trying to convert binary strings to decimal.
Getting an error only on 32 bit binary strings. I've marked where I think the error could be, but not shore.
1, 2, 4, 8, & 16 splits are fine.
Perhaps some kind soul can explain where I'm going wrong.
Regards
Maybe thia question does not belong on this forum, feel free to delete.
Code:
QList<quint64> uintList = QList<quint64>();
int split = 32; // 1, 2, 4, 8, 16, 32 byte data split
QString data
= readEeprom
(eepromAdd, startAdd, bytesToRead, i2c
);
int dl = data.length();
if (dl %split != 0) {
qDebug() << "Data length is not wholly divisible by split - (" << split << ")";
return; //exit(1);
}
qDebug() << "data - " << data << "-" << dl << "bytes -" << "split =" << split << endl;
int count = 0;
for (int i = 0; i < dl; i += split) {
hex = data.mid(i, split);
qDebug() << "hex1 - " << hex;
qDebug() << "dec1 - " << hex.toULongLong(&ok, 16); // *** this is wrong on 32 byte splits
tmpReturn = bReturn = hexToBinary(hex);
uintList.append(hex.toULongLong(&ok, 16)); //some sort of error handling on &ok // ***suspect error here***
qDebug() << count + 1 << "-" << "split" << split << uintList << "*** decimal" << uintList[count]
<< "- hexToBinary" << bReturn
<< "- binaryToHex" << binaryToHex(tmpReturn.remove(" "))
//<< "- binaryToDec" << binaryToDec(bReturn.remove(" ").rightJustified(split, '0'))
//<< "- decToBinary" << decToBinary(uintList[count]).rightJustified(split * 4, '0'); //pad with leading zeros
;
Code:
QString myProg
::binaryToHex(QString sBin
) { // eg. sBin = "00000000000011110000000000010000" qDebug() << "sbin1 - " << sBin; //ok
qDebug
() <<
"sbin2 - " << sBin.
remove(QRegExp("^[0]*"));
//ok
const std
::string bin
= sBin.
remove(QRegExp("^[0]*")).
toStdString();
quint64 result = 0;
for(size_t count = 0; count < bin.length(); ++count) {
result *=2;
result += bin[count]=='1'? 1 :0;
}
qDebug() << "len - " << bin.length(); //ok
qDebug() << "res - " << result; //ok
return (res);
}
Code:
data - "000100020003000400050006000700080009000a000b000c000d000e000f0010" - 64 bytes - split = ??
split = 8
hex1 - "000f0010"
dec1 - 983056
sbin1 - "00000000000011110000000000010000"
sbin2 - "11110000000000010000"
len - 20
res - 983056
8 - split 8 (65538, 196612, 327686, 458760, 589834, 720908, 851982, 983056) *** decimal 983056 - hexToBinary "0000 0000 0000 1111 0000 0000 0001 0000" - binaryToHex "f0010"
split = 16
hex1 - "000d000e000f0010"
dec1 - 3659234827763728
sbin1 - "0000000000001101000000000000111000000000000011110000000000010000"
sbin2 - "1101000000000000111000000000000011110000000000010000"
len - 52
res - 3659234827763728
4 - split 16 (281483566841860, 1407400653815816, 2533317740789772, 3659234827763728) *** decimal 3659234827763728 - hexToBinary "0000 0000 0000 1101 0000 0000 0000 1110 0000 0000 0000 1111 0000 0000 0001 0000" - binaryToHex "d000e000f0010"
split = 32
hex1 - "0009000a000b000c000d000e000f0010"
dec1 - 0
sbin1 - "00000000000010010000000000001010000000000000101100000000000011000000000000001101000000000000111000000000000011110000000000010000"
sbin2 - "10010000000000001010000000000000101100000000000011000000000000001101000000000000111000000000000011110000000000010000"
len - 116
res - 3659234827763728 *** should be 5188234733137453056 - max value quint64 18446744073709551615***
2 - split 32 (0, 0) *** decimal 0 - hexToBinary "0000 0000 0000 1001 0000 0000 0000 1010 0000 0000 0000 1011 0000 0000 0000 1100 0000 0000 0000 1101 0000 0000 0000 1110 0000 0000 0000 1111 0000 0000 0001 0000" - binaryToHex "d000e000f0010"
Re: Problem with number types - convert binary QString to decimal
My approach to problems like this is to use a reference to the type you want to convert the data to
Example
Code:
// assuming data is 32 bit integer
int Conversion::Integer(
const unsigned int index,
{
int i;
char *c;
unsigned int cntr;
assert((index + sizeof(int) -1) < static_cast<unsigned int>(array.size()));
c = (char*)(&i);
for(cntr = 0;cntr < sizeof(int);cntr++)
{
*(c + cntr) = array[index + cntr];
}
return i;
}
In my example I am interested in converting part of the input data into a 32 bit integer. The input 'index' value is the offset from where to start the data conversion in the input array data. The pointer character 'c' is a reference to the same address (stack) space as the returned integer 'i'. When you modify the text contents of 'c' you are also changing the binary data of 'i'.
QByteArray has methods to convert to and from hexadecimal. Your data (i.e. "000100020003000400050006000700080009000a000b000c0 00d000e000f0010") is in hexadecimal. If you want to extract integer, floating point values, text, or whatever from your data you need to convert it from hex first. Prior to calling the above example you must call QByteArray::fromHex(...) to convert "000100020003000400050006000700080009000a000b000c0 00d000e000f0010" to actual binary data.
Re: Problem with number types - convert binary QString to decimal
Quote:
Originally Posted by
jimbo
I'm trying to convert binary strings to decimal.
I am not really sure I understand what you're trying to accomplish. You state you want to convert to decimal, yet you appear to want to convert to the hex equivalent of your binary string. Is there a reason you can't do something as simple as:
Code:
book ok;
QString binary
= "00000000000011110000000000010000";
qint64 dec = binary.toLongLong(&ok, 2);
hex.sprintf("%llx", dec);
qDebug() << "bin=" << binary;
qDebug() << "dec=" << dec;
qDebug() << "hex=" << hex;
Re: Problem with number types - convert binary QString to decimal
Hello jefftee,
Thanks for your example, its a lot shorter than mine. (my ignorance)
I think I should have been more explicit with my problem.
Splits at 1, 2, 4, 8 and 16 give corrrect results.
The problem is with the 32 bit split, decimal and hex return "0" with your code and mine.
I think its probably a problem with overflow and number types. (don't know)
Regards
Code:
qDebug() << "data - " << data << "-" << dl << "bytes -" << "split =" << split << endl;
for (int i = 0; i < dl; i += split) {
hex = data.mid(i, split);
tmpReturn = hexToBinary(hex); //my hexToBinary() tested and works.
qDebug() << "hex 1 - " << hex;
qDebug() << "bin - " << tmpReturn;
bool ok;
QString binary
= tmpReturn.
remove( " ");
qint64 dec1 = binary.toLongLong(&ok, 2);
if (!ok) qDebug() << "error";
hex.sprintf("%llx", dec1);
qDebug() << "bin2 = " << binary;
qDebug() << "dec2 = " << dec1;
qDebug() << "hex2 = " << hex;
qDebug() << "";
}
Code:
//Output for a 16 bit split
data - "000100020003000400050006000700080009000a000b000c000d000e000f0010" - 64 bytes - split = 16
//Loops 0, 1, and 2 omittted.
hex 1 - "000d000e000f0010"
bin - "0000 0000 0000 1101 0000 0000 0000 1110 0000 0000 0000 1111 0000 0000 0001 0000"
bin2 = "0000000000001101000000000000111000000000000011110000000000010000"
dec2 = 3659234827763728
hex2 = d000e000f0010"
Code:
//Output for a 32bit split
data - "000100020003000400050006000700080009000a000b000c000d000e000f0010" - 64 bytes - split = 32
//Loop 0 omittted.
hex 1 - "0009000a000b000c000d000e000f0010"
bin - "0000 0000 0000 1001 0000 0000 0000 1010 0000 0000 0000 1011 0000 0000 0000 1100 0000 0000 0000 1101 0000 0000 0000 1110 0000 0000 0000 1111 0000 0000 0001 0000"
error
bin2 = "00000000000010010000000000001010000000000000101100000000000011000000000000001101000000000000111000000000000011110000000000010000"
dec2 = 0
hex2 = "0"
Re: Problem with number types - convert binary QString to decimal
Integer overflow is certainly your issue. See the data below for min/max and sizes for qlonglong:
qlonglong size (bytes) = 8
qlonglong bits = 64 (8 bits/byte times 8 bytes = 64 bits with 63 for precision 1 for sign)
qlonglong min = -9,223,372,036,854,775,808
qlonglong max = +9,223,372,036,854,775,807
What you refer to as a 16-bit split actually requires 64 bits or 8 byte precision, which does not overflow a qlonglong. i.e. You are taking 16 positions from the string, each requires 4 bits to represent the range of possible 0-F values, for a total of 16 x 4 = 64 bits.
What you are calling a 32-bit split would actually require an integer data type with 128 bit or 16 byte precision, which will overflow a qlonglong or qulonglong. i.e. You are taking 32 positions, each requires 4 bits to represent the range of possible 0-F values, for a total of 32 x 4 = 128 bits or 16 bytes.
So, your quest for a 32-bit split [sic] is not possible, nor do I see why you would even care to do so. Since your code works for "splits" up to 16 positions (or the more simplified code I provided also works), is/was this just some educational exercise or why do you perceive the need to process in 32 position chunks?
Re: Problem with number types - convert binary QString to decimal
Hello jefftee,
Quote:
is/was this just some educational exercise
Yes, I'm afraid so! While I'm trying to learn.
Thank you for your time and effort.
Regards
Re: Problem with number types - convert binary QString to decimal
Heh, not a problem, glad I could help. I just wanted to make sure there wasn't something I was missing. Believe me, I've been down many rabbit holes myself trying to understand why something worked or didn't work accordingly, so I completely understand!