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

问题描述

下面是我编写的用于找到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,所以无论是天花板还是地板,在这三种情况下输出都应该为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函数也不精确。结果通常很少有错误。在您的情况下,您得到的不是精确的3,但是有些值略大于3。将ceilfloor应用于这种不精确的结果时,您可能会增加或减少误差量到一个整数。在这种情况下,您通过将结果从几乎正确的整数上限为紧随其后的整数来增加错误。

,

如果要查找相对于给定基数的整数的指数,则重复除法并检查余数是一个很好的起点。有更多更快的方法(与通过平方求幂有关),可以调查是否想获得更多性能。

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

最后,不要在#define ll long long上这样做。它仅用于混淆。而且#include<bits/stdc++.h>不是可移植的C ++。