3

我在数字(浮点数)到字符串的转换中发现了一些奇怪的东西..

这是示例代码。

#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QString>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug()<<QString::number(50.5, 'f', 0);
    qDebug()<<QString::number(49.5, 'f', 0);

    return a.exec();
}

这里的输出是

Starting /home/asit/qt/qstring1-build-desktop/qstring1...
"50" 
"50"

输出应该是 51 和 50。有人能说出这个输出背后的原因吗?

4

3 回答 3

7

浮点数的问题在于它们无法准确表示。所以 49.5 可能存储为比 49.5 稍大的数字。这同样适用于 50.5,但这个可能存储为略小于 50.5 的数字。

这让我在 Linux 上尝试过将 double 类型转换为 int。以例如

double value = 0.3;
int result = static_cast<int> (value * 1000);

在例如 Solaris SPARC 上,您将得到 300,如您所愿。在 Linux 上使用 gcc,你得到 299。为什么?好吧,尽管两者都通过向下舍入将双精度数转换为整数,但在 Linux 上的 gcc 上,双精度数被分配给 FPU 80 位寄存器,它由略小于 0.3 的数字表示。在 Solaris(实际上是大多数其他系统,包括 VC++)上,double 被分配给一个 64 位寄存器,在该寄存器中它被表示为略大于 0.3。

如果您想确保将数字四舍五入为正确值,只需在投射前添加 0.5 或使用 qRound() 即可。

于 2013-02-11T15:19:24.567 回答
0

输出正确。阅读手册,例如 QString Class ReferenceArgument Formats

你只是输出,而不是修改。如果您想获取int数字,请添加 0.5 add cast to int,例如:

...
int toInt(float x)
{
    return int(x+0.5);
}
...
qDebug()<<toInt(50.5);
qDebug()<<toInt(49.5);
于 2013-02-11T15:27:43.757 回答
0

数字 49.5 和 50.5 以 IEEE 浮点数精确表示。

但 IEEE 浮点标准支持各种舍入算法。除非您采取明确的步骤来控制使用哪种舍入算法,否则您将获得您的环境选择的默认算法。

具体来说,您的环境似乎正在使用银行家的四舍五入。当一个数字正好在两个可能结果的中间时,银行家的四舍五入将其四舍五入,以使最后一位为偶数。

所以 49.5 轮到 50。50.5 也轮到 50。

另请参阅此答案: Qt: Roundoff of 12.625 by 2 返回 12.62

于 2020-03-06T21:30:27.950 回答