cmath精度误差中的楼层函数
Floor functions in cmath precision error
所以我最近在尝试一个涉及浮点运算的问题。下面是该代码的片段。
#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 %llun",ull(ans1),ull(ans2));
}
输出:
20833333333333333 20833333333333332
在这个问题中,我不得不在决赛中四舍五入。我首先使用了 cmath 的圆形函数,但得到了 WA。然后经过一些谷歌搜索,我发现了这种很好的简单方法来四舍五入一个 no
n = floor(n + 0.5);
但令我惊讶的是地板功能的奇怪行为。当与 std 命名空间一起使用时,它的行为不同,实际上它只有在那时才能正确运行。
我的猜测是,来自 std 命名空间的地板函数返回一个长双精度值,而来自 cmath 的普通地板函数返回一个双精度值,因此精度损失。
所以我想知道的是为什么这两个函数在 cmath 中位于不同的命名空间中,如果编译器选择合适的地板函数不是更好吗,因为我正在传递给它一个"长双精度",就像普通方法重载一样。
谢谢
cmath 的 floor
函数是 C 的遗产,在C++提出 floor
的 long double
版本之前就在这里......现在我们无法删除它,因为它被使用,所以新的是在 std 中创建的。
floor(ans+0.5)
会将(ans + 0.5)
转换为"正常"双精度,因此会失去精度。
相关文章:
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 为什么我的数组双精度函数不起作用?
- 如果存在从"双精度"到"T"的转换,则禁用构造函数
- f 是指向函数的指针,该函数采用 int,并返回指向不带任何内容并返回双精度的函数的指针
- 我在C++中使用提升哈希函数将 3 个双精度组合成一个面临冲突的哈希
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 从 C++ 中的函数返回双精度的问题
- Fmod 函数清楚地输出一个预期的双精度值,但 if(fmod == 预期的双精度值)的计算结果不是 true
- 函数重载和双精度和长之间的混淆
- C++采用浮点数或双精度的模板函数
- 对需要双精度数组和结构作为输入C++ DLL 函数的 C# 调用
- 带有映射的 Lambda 函数,其中键是元组,值是双精度
- 有没有办法构造一个 constexpr 函数来获取双精度的位表示
- 函数双精度,整数如何工作?C++
- 这是为浮点数/双精度函数泛型的正确方法吗?
- 当将变量作为函数参数传递时,由于隐式铸造而导致的精度丧失
- 如何根据精度轻松模板化数学函数
- 双精度/整数模板函数的向量