所以我最近尝试了一个涉及浮点运算的问题。下面是该代码的片段。
#include<cstdio>
#include<cmath>
typedef unsigned long long ull;
int main(){
long double n=1000000000,ans,ans1,ans2;
ans = (n*n/48.0);
ans1 = std::floor(ans+0.5); // Correct, got AC with this
ans2 = floor(ans+0.5); // Incorrect, got me 2 WA :(
printf("%llu %llu\n",ull(ans1),ull(ans2));
}
输出:
20833333333333333 20833333333333332
在问题中我不得不围绕最后的问题。我首先使用来自cmath的圆形函数,但得到了WA。然后经过一些谷歌搜索,我找到了这个简单的方法来绕过一个没有
n = floor(n + 0.5);
但令我惊讶的是地板功能的奇怪行为。当与std命名空间一起使用时,它的行为会有所不同,实际上它只在那时表现正常。
我的猜测是std命名空间的floor函数返回long double,而cmath的normal floor函数返回double,因此精度损失。
所以我想知道为什么这两个函数在cmath中位于不同的命名空间中,如果编译器选择了适当的floor函数就不会更好,因为我传递了一个'long double',就像普通的方法重载一样。
由于
答案 0 :(得分:2)
来自cmath的floor
函数是来自C的遗产,它就在C ++提出long double
floor
版{...}}之前......现在我们无法删除它,因为它已被使用,所以新的是在std。
中创建的
floor(ans+0.5)
会将(ans + 0.5)
转换为'普通'双精度,因此精度会降低。