我有一个将 QByteArray
转换为 float
的函数,它工作得很好,除非我给它填零,我得到 5.87747e-39
而不是 0.0
。
float QByteArrayToFloat(QByteArray f){
bool ok;
int sign = 1;
f = f.toHex(); // Convert to Hex
qDebug() << "QByteArrayToFloat: QByteArray hex = " << f;
f = QByteArray::number(f.toLongLong(&ok, 16), 2); // Convert hex to binary
if(f.length() == 32) {
if(f.at(0) == '1') sign =-1; // If bit 0 is 1 number is negative
f.remove(0,1); // Remove sign bit
}
QByteArray fraction = f.right(23); // Get the fractional part
double mantissa = 0;
for(int i = 0; i < fraction.length(); i++){ // Iterate through the array to claculate the fraction as a decimal.
if(fraction.at(i) == '1')
mantissa += 1.0 / (pow(2, i+1));
}
int exponent = f.left(f.length() - 23).toLongLong(&ok, 2) - 127; // Calculate the exponent
qDebug() << "QByteArrayToFloat: float number = "<< QString::number(sign * pow(2, exponent) * (mantissa + 1.0),'f', 5);
return (sign * pow(2, exponent) * (mantissa + 1.0));
}
QByteArray
中没有有用的函数(isEmpty()
不起作用)检查零。我可以(在 toHex()
之后)if(f.indexOf("00000000") == -1) return 0.0;
或 if(exponent = - 127 && mantissa == 0) return 0.0;
,但是有没有更优雅的方案呢?
此外,有趣的是 QString::number(sign * pow(2, exponent) * (mantissa + 1.0),'f', 5);
工作正常并打印 “0.00000”
。但是,一旦我使用 toFloat(&ok);
将其转换回 float 状态,同样的事情就会发生。
最佳答案
我从这个 document 中引用:
Denormalized Numbers
If you have an exponent field that's all zero bits, this is what's called a denormalized number. With the exponent field equal to zero, you would think that the real exponent would be -127, so this number would take the form of 1.MANTISSA * 2-127 as described above, but it does not. Instead, it is 0.MANTISSA * 2-126. Notice that the exponent is no longer the value of the exponent field minus 127. It is simply -126. Also notice that we no longer include an implied one bit for the mantissa.
Zero
You can think of zero as simply another denormalized number. Zero is represented by an exponent of zero and a mantissa of zero. From our understanding of denormalized numbers, this translates into 0*2-126 = 0. This sign bit can be either positive (0) or negative (1), leading to either a positive or negative zero. This doesn't make very much sense mathematically, but it is allowed.
将您的代码更正为零大小写后:
int exponent = - 126;
// and
return (sign * pow(2, exponent) * (mantissa + 0.0));
我得到的答案是 0.0。
关于c++ - QbyteArray要 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36859447/