【发布时间】:2016-08-19 22:59:48
【问题描述】:
我有一个将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); 浮动,同样的事情就会发生。
【问题讨论】:
-
如果字节数组包含浮点变量的内存表示,您可以使用
QDataStream(f) >> myFloat避免重新发明轮子。 -
@Murphy 内存表示是什么意思?我尝试了
QDataStream方法,但我得到0.0作为所有输入的结果 -
这就是浮点值在 RAM 中的存储方式,具体取决于您的编译器和架构如何处理它们。如果数组来自不同的来源,那么表示当然可能会有所不同;您可以尝试在读取流之前更改字节顺序是否可以解决此问题(
QDataStream的默认值是大端,使用英特尔机器您可能有小端)。 -
@Murphy 我试过
float a; QDataStream output(f); output.setByteOrder(QDataStream::LittleEndian); // and BigEndian output >> a;,但我的所有输入仍然为零
标签: c++ qt floating-point qbytearray