clang-tidy [bugprone-incorrect-roundings]支票的文件说:
数字0.499999975(最小可表示的浮点数低于0.5)舍入到1.0
据我所知,0.5
以下的最小浮点数是0.4999999702
,而不是0.499999975
。但尽管如此,两个数字give me 0
values在天真的舍入计算:
#include <iostream>
int main() {
const float v1 = 0.499999975;
const float v2 = 0.4999999702;
std::cout << (int)(v1+0.5) << "\n"
<< (int)(v2+0.5) << "\n";
}
我错过了什么吗?
关于标准中的算术转换:
6.3.1.8通常的算术转换
...
- 否则,如果任一操作数的对应实数类型为double,则将另一个操作数转换为对应的实类型为double的类型,而不更改类型域。
- 浮动操作数的值和浮动表达式的结果可以以比该类型所需的精度和范围更高的精度和范围来表示;
所以在这一行:
(int)(v1+0.5)
你的v1
变量被提升为双精度浮点运算,这就是你得零的原因。
这应该可以解决您的问题:
#include <iostream>
int main() {
const float v1 = 0.499999975f;
const float v2 = 0.4999999702f;
std::cout << (int)(v1 + 0.5f) << "\n"
<< (int)(v2 + 0.5f) << "\n";
}