C++ 三的幂是多少?

C++ 三的幂是多少?,c++,floating-point,logarithm,C++,Floating Point,Logarithm,Leet代码326。三的力量: 给定一个整数n,如果它是三的幂,则返回true。否则,返回false 如果存在一个整数x,使得n==3x,则整数n是三的幂 我的代码 bool isPowerOfThree(int n) { if(n == 0) return false; double x = log(n)/log(3); if(x == ceil(x)) return true; return false; } 为什么我得到了

Leet代码326。三的力量:

给定一个整数n,如果它是三的幂,则返回true。否则,返回false

如果存在一个整数
x
,使得
n==3x
,则整数n是三的幂

我的代码

bool isPowerOfThree(int n) {
    if(n == 0)
        return false;
    double x = log(n)/log(3);
    if(x == ceil(x))
        return true;
    return false;
}
为什么我得到了
n=243
的错误答案?
I
cout
这两个
x
ceil(x)
都是相等的。

另外,当我使用log10而不是log时,它会被接受,但当我使用log2而不是log时,它会再次失败。

一个不使用对数的简单且被接受的解决方案:

bool isPowerOfThree(int n) {
        if (n <= 0) return false;
        
        long int a = 1;
        
        while (a < n)
        {
            a *= 3;
        }
                
        return a == n;
    }
bool isPowerOfThree(int n){

if(n浮点算法设计为近似实数算法。基于二进制的浮点格式将有限数表示为按二次幂缩放的整数(限制整数和幂的范围)

log(243)和log(3)具有无理值,因此不能表示为按二的幂缩放的整数。与log(243)最接近的值是5.49306144334054824440721595952067989044189453125,该值可用
双精度
(IEEE-754 binary64)常用的格式表示,即6184637367337933•2−50.可表示的与日志(3)最接近的值为1.09861228866810978210821758693778261268138885498046875,即4947709893870347•2−五十二

当这两个数字以
double
格式分开时,结果是4.9999999999999111821580299877476766109466552734375。显然,这不等于上限5,因此测试例程返回false

浮点运算中出现的舍入误差各不相同,因此使用
log10
而不是
log
可能会碰巧在
log10
和取消的除法中得到舍入误差,导致计算出的商为5。此外,库函数如
log
的实现质量也不同它并不总是返回最接近的可表示值


一般来说,您应该避免在此类测试中使用浮点运算。重新设计代码以使用整数运算。

double
这样的浮点数本质上是不精确的-您能想到一种只使用整数的解决方案吗?
log(243)/log(3)
并不精确地说是
5
。(这是在数学中,但不是在浮点运算中。)为了证明这一点,请尝试
std::log(243)/std::log(3)-5
:。但是当使用log10而不是log时,我得到了正确的答案,leetcode甚至接受了我的代码。有时你赢了,有时你输了……这并没有改变浮点运算的规则…;-)谢谢,但我后来也做了同样的逻辑。我要寻找的是在2或自然对数的情况下出错的错误,而不是在普通算法(以10为基数)的情况下。(a)没有解释的代码不是一个好答案。(b)问题不仅仅是“如何测试一个数字是否是三的幂?”而是具体的问题“为什么我得到了
n=243
的错误答案?这篇文章没有回答这个问题。