Qt qreal计算错误
Qt qreal calculates wrong
我想用QSpinBox
编辑QGraphicsItem
的不透明度。QSpinBox
给了我值57,我用它来设置项目的不透明度。 然后我从项目中恢复了更改的不透明度,并想填充QSpinBox
.但是设置框的值会导致错误。
qDebug() << (int)(qreal)(0.57 * 100.0);
产出56
这是一个已知的错误吗? 有解决方法吗?
原因
不要依赖浮点数的精度,因为它的计算不准确。您可以在此处或此处阅读有关此问题的更多信息。
示范
如果使用qSetRealNumberPrecision
为输出设置更高的精度,您将看到问题的实际根源 –0.57 * 100.0
的结果不是精确57,而是类似于 56.999999999999992895:
qDebug() << qSetRealNumberPrecision(20) << 0.57 * 100.0;
溶液
因此,最好简单地将数字四舍五入到最接近的整数,而不是转换为int
只是省略分数:
qDebug() << qRound(0.57 * 100.0);
适合尾数的整数在浮点中具有精确的表示形式,因此static_cast<qreal>(100.0) == 100
始终成立并表示为100*2^0
。
具有形式分母的有理数2^-n
只要分子适合尾数,在浮点中也有精确的表示,因此例如 只要编译器不使用脑死亡十进制到浮点转换函数,static_cast<qreal>(0.25*4) == 1
就成立。当大多数编译器解析代码时,它们会将0.25
和4
转换为浮点表示形式,然后执行乘法以获取常量表达式的值。
但是static_cast<qreal>(0.57)
没有表示为m*2^-n
,整数m,n
足够小,并且必然表示得不精确。它可以表示为小于或大于0.57
。 因此,当您将其乘以100
时,它可以略小于57
- 在您的情况下。
最简单的解决方法是避免往返:将不透明度作为整数存储在任何地方,并且仅在更改值时从整数转换为浮点数。换句话说,永远不要使用setOpacity()
方法,而永远不要使用opacity()
方法。使用项目的数据属性存储整数值不透明度:
void setOpacity(QGraphicsItem * item, int opacity) {
item->setData(kOpacity, opacity);
item->setOpacity(opacity / 100.0);
}
void getOpacity(QGraphicsItem * item) {
auto data = item->data(kOpacity);
if (! data.isNull())
return data.toInt();
int opacity = round(item->opacity() * 100.0);
setOpacity(item, opacity);
return opacity;
}
我找到了一个临时解决方案,但我对此不满意。
qDebug() << "qreal" << (int)(qreal)(0.57 * 100.0);
qDebug() << "double" << (int)(double)(0.57 * 100.0);
qDebug() << "float" << (int)(float)(0.57 * 100.0);
输出: Qreal 56, 双56, 浮点数 57
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- OpenCV - Python 断言错误:SAD 算法 - 立体相机视差图计算
- 如何在常量计算表达式中获取编译时错误?
- 计算阶乘的 C++17 倍表达式中的错误
- 为什么 2 个双精度值之间的差值计算错误?
- 我在c++中遇到了一个奇怪的错误,其中一个计算2个小整数加法的语句溢出到一个长值中
- 错误 C2064:术语的计算结果不是采用 3 个参数的函数
- 错误:一元"*"的类型参数无效(具有"int"):使用 mergesort 计算
- C++ openmp 并行计算计算错误的结果
- 为什么按位运算符在使用与整数中提供的位数相同的位数计算可能的最大范围时会产生错误
- 术语不计算为函数采用 1 个参数错误?
- Travis CI 中奇怪的编译器错误不会在本地计算机上发生
- 点云库:计算筛选关键点 - 输入云错误
- 在线程错误 C2064 中:term 的计算结果不为 0 个参数的函数
- GetAsyncKeyState(VK_RETURN) 错误地计算为 true
- 错误 C2064:term 的计算结果不是采用 1 个参数的函数 - 关于线程的一些东西
- log2 计算在 CPP 中给出了错误的结果
- 错误计算RSI或错误在MetaTrader 4
- c++程序错误计算