为什么 floor 和 ceil 值在 C++ 中给出不同的整数值

Why floor and ceil value giving different values for an integer in c++

下面是我为求 6 的指数而编写的程序,但我给出了错误的输出或者我可能某处有误,我在这里无法弄清楚。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    ll t;
    cin>>t;
    cout<<log(t)/log(6)<<"\n";
    cout<<floor(log(t)/log(6))<<"\n";
    cout<<ceil(log(t)/log(6));
    return 0;
}

输入:-

216

输出:-

3

3

4

由于216可以写成6*6*6,所以无论有ceil还是floor,三种情况输出都应该是3。

回答我自己的问题,这个问题可以通过设置小精度(这里最多2个小数位)来解决,下面是相同的程序。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    cout<<log(t)/log(6)<<"\n";
    cout<<floor((floor(log(t)/log(6)*100.0)/100.0))<<"\n";
    cout<<ceil((floor(log(t)/log(6)*100.0)/100.0));
    return 0;
}

如果你想找到一个整数相对于给定基数的指数,那么重复除法和检查余数是一个很好的起点。如果您想获得更多性能,可以研究一些更快的方法(与平方求幂相关)。

问题是使用两个 log 调用的比率并将其截断为 int 必然会给您一个不准确的答案,因为 log 的结果很可能不能精确地表示为浮点值,并且 log 函数本身可能无法恢复可能的最佳浮点值(C++ 标准和 IEEE754 都没有坚持这一点)。

最后,在 #define ll long long,不要那样做。它只会混淆视听。 #include<bits/stdc++.h> 不是可移植的 C++。

log 函数 - 与大多数浮点计算一样 - 不精确。结果中通常存在微小的错误。在你的情况下,你没有得到确切的 3,但有些值略大于 3。当你将 ceilfloor 应用于这种不精确的结果时,你可能会增加或减少错误量到一个整数。在这种情况下,您通过将几乎正确的整数的结果上限设置为正好跟随的整数来增加错误)。