c++ - QbyteArray要 float

标签 c++ qt floating-point qbytearray

我有一个将 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/

相关文章:

C++ 无法创建 vector

javascript - QML:将 Canvas 作为 ShaderEffectSource 传递

c++ - 从源加入RTP组播

c++ - 自定义模板 memcmp 与 C memcmp

python - 导入 PySide2 时出现 ImportError

c++ - 连接lambda时如何将Qt::ConnectionType传递给QObject::connect?

c - 如何将 float 分成整数和小数部分?

python - 将 pandas 中的 float 转换为字符串时精度损失

c - 关于 C 中的 float 数据类型

c++ - 默认值的函数模​​板