C++ cmath精度误差中的Floor函数
所以我最近尝试了一个涉及浮点运算的问题。下面是该代码的一个片段C++ cmath精度误差中的Floor函数,c++,algorithm,floating-point,floating-point-precision,C++,Algorithm,Floating Point,Floating Point Precision,所以我最近尝试了一个涉及浮点运算的问题。下面是该代码的一个片段 #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
#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));
}
在这个问题中,我必须对最后的ans进行四舍五入。我首先使用了cmath的四舍五入函数,但得到了WA。在谷歌搜索之后,我找到了一个简单的方法来绕过一个“不”
n = floor(n + 0.5);
但令我惊讶的是楼层功能的怪异行为。当与std名称空间一起使用时,它的行为会有所不同,实际上,只有在这种情况下,它的行为才会正确
我猜std名称空间中的floor函数返回一个长double,而cmath中的普通floor函数返回一个double,因此精度降低
因此,我想知道的是,为什么这两个函数在cmath中位于不同的名称空间中,如果编译器选择适当的floor函数不是更好吗?因为我正在传递一个“长双精度”,就像正常的方法重载一样
<代码>地板(ANS + 0.5)< /C> >将代码< >(ANS + 0.5)< /C> >为“正常”的双,因此丢失精度。但为什么需要添加STD命名空间,我的意思是为什么直接在CMASK中?当他们创建C++命名空间时,他们放置了新的东西。C仍然存在并且仍然被使用(例如对于嵌入式系统或Linux内核),C++作为C级的一个层,它不能改变C程序的行为。使用名称空间可以避免与旧方法发生任何冲突(即使这些旧方法应该在博物馆中,而不是在我们的.h文件中)。“在谷歌搜索了一番之后,我发现了一种很好的绕过“不”的简单方法,而你发现的方法不起作用。实际上,我刚刚看到有一个std函数roundl,它以longdouble作为输入,这正是我想要的:)
n = floor(n + 0.5);