67

I saw this question, and pop up this idea.

Community
  • 1
  • 1
Mask
  • 33,129
  • 48
  • 101
  • 125
  • 9
    Questions often give rise to new questions, but I recommend considering generalizations. e.g. "power of N?" where N is an arbitrary integer. – Michael Easter Nov 26 '09 at 18:30
  • 3
    @Michael: I just added an answer that is even faster than the one by starblue: My algorithm's worst case is just five divides. In my answer I also discuss the general case of "power of N". – Ray Burns Feb 04 '10 at 10:23
  • 3
    This is silly. What is next? Power of 5? – Alexandre Santos Jun 17 '14 at 23:28
  • @AlexandreSantos exactly! It has been asked in a technical interview; power of 5! – Hengameh May 23 '15 at 11:11
  • Check out this: http://stackoverflow.com/a/30411999/4723778 – Hengameh May 23 '15 at 11:31
  • Then again, 3 and 5 (as 7, 9, 15, 17, ...) are a power of two +/- 1, and funny tricks about "digit" sums apply. – greybeard May 23 '15 at 11:44
  • Possible duplicate of [Check if one integer is an integer power of another](http://stackoverflow.com/questions/4429044/check-if-one-integer-is-an-integer-power-of-another) – azam Aug 13 '16 at 22:23
  • That question is for 2 and computers are based on binary, so we could get a different ( and specific) answer based on binary calculations. But there is nothing such as trinary, finary etc. ( Isn't it ?) So, this should be a general question. – azam Aug 13 '16 at 22:32

25 Answers25

120

There exists a constant time (pretty fast) method for integers of limited size (e.g. 32-bit integers).

Note that for an integer N that is a power of 3 the following is true:

  1. For any M <= N that is a power of 3, M divides N.
  2. For any M <= N that is not a power 3, M does not divide N.

The biggest power of 3 that fits into 32 bits is 3486784401 (3^20). This gives the following code:

bool isPower3(std::uint32_t value) {
    return value != 0 && 3486784401u % value == 0;
}

Similarly for signed 32 bits it is 1162261467 (3^19):

bool isPower3(std::int32_t value) {
    return value > 0 && 1162261467 % value == 0;
}

In general the magic number is:

3^floor(log_3 MAX) == pow(3, floor(log(MAX) / log(3)))

Careful with floating point rounding errors, use a math calculator like Wolfram Alpha to calculate the constant. For example for 2^63-1 (signed int64) both C++ and Java give 4052555153018976256, but the correct value is 4052555153018976267.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Elric
  • 1,301
  • 1
  • 8
  • 3
  • 1
    The property specified in 1 and 2 is true for all the prime numbers. isn't it? So can we check if an integer is a power of 2,3,5,7,11... using this procedure? – Mohammad Mamun Hossain Mar 03 '18 at 08:17
  • 1
    but it's need to know numbers 3486784401 or 1162261467 how to get it using only * ?It's the same as consecutive division to 3 of original number – J.J. Beam Dec 09 '19 at 19:34
  • One shouldn't say "C++ gives this number". C++ is too underspecified to give any particular number. On my x86 Linux GCC, I get the correct value from `std::pow(3.L, std::floor(std::log((1ull<<63)-1.L)/std::log(3.L)))`. (Note the `long double` literals here, which do the trick.) – Ruslan Dec 05 '20 at 19:23
  • A correction in the calculations above... The correct value of 2^63-1 is 9223372036854775807. If you calculate 2^63 using Java's pow() method and do a typecast to int, then it results in truncation and yields 2147483647. – bincob Dec 02 '21 at 06:14
88
while (n % 3 == 0) {
    n /= 3;
}
return n == 1;

Note that 1 is the zeroth power of three.

Edit: You also need to check for zero before the loop, as the loop will not terminate for n = 0 (thanks to Bruno Rothgiesser).

starblue
  • 55,348
  • 14
  • 97
  • 151
  • 27
    I will comment here, since it is currently (and I hope remains) the top-voted answer. For all the folks who want to avoid division by multiplying: The reason this answer will typically beat yours is that for most input, it won't have to divide very many times. Two thirds of random input will be eliminated after a single mod and compare. Multiplication-based answers have to keep multiplying until the accumulator meets or exceeds n, for ANY input. – John Y Nov 26 '09 at 16:25
  • 5
    You cannot get much simpler or clearer than this algorithm. In pure mathematics, we would use logarithms. On computers, we would use starblue's example code instead. – Noctis Skytower Nov 26 '09 at 18:01
  • @Noctis: There are real-world applications that require both big integers and speed. – jfs Nov 26 '09 at 23:13
  • JohnY, avoiding multiplication by dividing twice as often (and the fact that it doesn't handle zero) does not make for a good answer. – Marcelo Cantos Dec 16 '09 at 05:04
  • @Marcelo: On random input, it will not be dividing twice as often. In fact, for two-thirds of random input, it will not even be dividing twice. – John Y Dec 16 '09 at 05:47
  • @Marcelo Cantos With the check for zero I think this is still the best solution for most practical cases. Most of the time it is fast enough, and the two divisions need not happen if the compiler replaces them with a single machine instruction that does both. Note that all the log "solutions" also neglect to check for zero and negative numbers, apart from their problem with floating point imprecision. – starblue Dec 16 '09 at 05:51
  • 3
    I read this and the other answers with interest, but the **fastest solution of all was not here.** I have posted another answer that is faster than this one and also faster than the if-tree idea because it avoids pipeline stalls (check it out...). I must say, however, that **I really like the simplicity of this answer** and would probably choose it over my own answer if I were writing anything but a library for which speed was the most important criterion. – Ray Burns Feb 04 '10 at 10:19
  • @Ray Burns Check out [my new answer below](http://stackoverflow.com/questions/1804311/how-to-check-if-an-integer-is-power-of-3/16249592#16249592). I think it should be competitive with the fastest solutions. – starblue Apr 27 '13 at 08:36
  • This is the best 'general' solution because it is 1) simple, and 2) modern compilers transform [division by constants into multiplications](https://gmplib.org/~tege/division-paper.pdf) (see: algorithm 4), yielding 3) a tight loop with no lookup tables, or memory access. – Brett Hale Aug 10 '15 at 15:12
  • @JohnY No way. This solution is slow, actually **very slow**. You can beat it using multiplication as the number of needed multiplications is also low. Without any assumptions about the input, you can beat it by binary search. And using a table of 32 elements, in a hot loop (no cache misses), you can get the answer in maybe 8 cycles, i.e., much faster than a single division. See [my answer](http://stackoverflow.com/a/41582594/581205). – maaartinus Jan 11 '17 at 04:19
  • @maaartinus - I never said this was the fastest solution, or even that it was fast. I said that it was faster than many naive multiplication-based solutions. By "naive" I mean that seven years ago, when this question was asked, some people were rushing to offer simple, easy, multiplication-in-a-loop answers that were slower than this one because they didn't use any other optimization techniques; and those answers *still* didn't beat this one for simplicity. Also note that the question doesn't mention anything about speed or efficiency. I still consider this the best overall answer. – John Y Jan 11 '17 at 16:33
  • @JohnY I actually mostly agree (I guess, I read your comment too fast). This solution is best, except in extreme cases and even then it's not to be discarded without a benchmark. There's one more thing: A compiler can usually replace division by multiplication which makes this solution much better. Even such a trivial thing like `x%3 == 0` can be [fun to optimize](http://codereview.stackexchange.com/a/52331/14363), but the simplest solution ist best nearly always. – maaartinus Jan 11 '17 at 17:18
44

I find myself slightly thinking that if by 'integer' you mean 'signed 32-bit integer', then (pseudocode)

return (n == 1) 
    or (n == 3)
    or (n == 9)
    ... 
    or (n == 1162261467) 

has a certain beautiful simplicity to it (the last number is 3^19, so there aren't an absurd number of cases). Even for an unsigned 64-bit integer there still be only 41 cases (thanks @Alexandru for pointing out my brain-slip). And of course would be impossible for arbitrary-precision arithmetic...

AakashM
  • 62,551
  • 17
  • 151
  • 186
  • 18
    for 64-bit integers you shouldn't get more than 64 cases. – Alexandru Nov 26 '09 at 15:58
  • 4
    You could expand out the constants: e.g. n = 3 * 3 or n = 3 ** 2. That way you could visually check for correctness. Typically your compiler will fold the constants for you, so there would be no loss of efficiency (that may not be the case in all languages/implementations). – dan-gph Nov 26 '09 at 16:13
  • 5
    You could use binary search to speed it up. – starblue Nov 26 '09 at 19:06
  • 5
    +1. With binary search, I'm sure this is the most efficient solution – Niki Nov 26 '09 at 22:22
32

I'm surprised at this. Everyone seems to have missed the fastest algorithm of all.

The following algorithm is faster on average - and dramatically faster in some cases - than a simple while(n%3==0) n/=3; loop:

bool IsPowerOfThree(uint n)
{
  // Optimizing lines to handle the most common cases extremely quickly
  if(n%3 != 0) return n==1;
  if(n%9 != 0) return n==3;

  // General algorithm - works for any uint
  uint r;
  n = Math.DivRem(n, 59049, out r); if(n!=0 && r!=0) return false;
  n = Math.DivRem(n+r, 243, out r); if(n!=0 && r!=0) return false;
  n = Math.DivRem(n+r,  27, out r); if(n!=0 && r!=0) return false;
  n += r;
  return n==1 || n==3 || n==9;
}

The numeric constants in the code are 3^10, 3^5, and 3^3.

Performance calculations

In modern CPUs, DivRem is a often single instruction that takes a one cycle. On others it expands to a div followed by a mul and an add, which would takes more like three cycles altogether. Each step of the general algorithm looks long but it actually consists only of: DivRem, cmp, cmove, cmp, cand, cjmp, add. There is a lot of parallelism available, so on a typical two-way superscalar processor each step will likely execute in about 4 clock cycles, giving a guaranteed worst-case execution time of about 25 clock cycles.

If input values are evenly distributed over the range of UInt32, here are the probabilities associated with this algorithm:

  • Return in or before the first optimizing line: 66% of the time
  • Return in or before the second optimizing line: 89% of the time
  • Return in or before the first general algorithm step: 99.998% of the time
  • Return in or before the second general algorithm step: 99.99998% of the time
  • Return in or before the third general algorithm step: 99.999997% of the time

This algorithm outperforms the simple while(n%3==0) n/=3 loop, which has the following probabilities:

  • Return in the first iteration: 66% of the time
  • Return in the first two iterations: 89% of the time
  • Return in the first three iterations: 97% of the time
  • Return in the first four iterations: 98.8% of the time
  • Return in the first five iterations: 99.6% of the time ... and so on to ...
  • Return in the first twelve iterations: 99.9998% of the time ... and beyond ...

What is perhaps even more important, this algorithm handles midsize and large powers of three (and multiples thereof) much more efficiently: In the worst case the simple algorithm will consume over 100 CPU cycles because it will loop 20 times (41 times for 64 bits). The algorithm I present here will never take more than about 25 cycles.

Extending to 64 bits

Extending the above algorithm to 64 bits is trivial - just add one more step. Here is a 64 bit version of the above algorithm optimized for processors without efficient 64 bit division:

bool IsPowerOfThree(ulong nL)
{
  // General algorithm only
  ulong rL;
  nL = Math.DivRem(nL, 3486784401, out rL); if(nL!=0 && rL!=0) return false;
  nL = Math.DivRem(nL+rL,   59049, out rL); if(nL!=0 && rL!=0) return false;
  uint n = (uint)nL + (uint)rL;
  n = Math.DivRem(n,   243, out r); if(n!=0 && r!=0) return false;
  n = Math.DivRem(n+r,  27, out r); if(n!=0 && r!=0) return false;
  n += r;
  return n==1 || n==3 || n==9;

}

The new constant is 3^20. The optimization lines are omitted from the top of the method because under our assumption that 64 bit division is slow, they would actually slow things down.

Why this technique works

Say I want to know if "100000000000000000" is a power of 10. I might follow these steps:

  1. I divide by 10^10 and get a quotient of 10000000 and a remainder of 0. These add to 10000000.
  2. I divide by 10^5 and get a quotient of 100 and a remainder of 0. These add to 100.
  3. I divide by 10^3 and get a quotient of 0 and a remainderof 100. These add to 100.
  4. I divide by 10^2 and get a quotient of 1 and a remainder of 0. These add to 1.

Because I started with a power of 10, every time I divided by a power of 10 I ended up with either a zero quotient or a zero remainder. Had I started out with anything except a power of 10 I would have sooner or later ended up with a nonzero quotient or remainder.

In this example I selected exponents of 10, 5, and 3 to match the code provided previously, and added 2 just for the heck of it. Other exponents would also work: There is a simple algorithm for selecting the ideal exponents given your maximum input value and the maximum power of 10 allowed in the output, but this margin does not have enough room to contain it.

NOTE: You may have been thinking in base ten throughout this explanation, but the entire explanation above can be read and understood identically if you're thinking in in base three, except the exponents would have been expressed differently (instead of "10", "5", "3" and "2" I would have to say "101", "12", "10" and "2").

Matt G
  • 2,373
  • 1
  • 14
  • 12
Ray Burns
  • 62,163
  • 12
  • 140
  • 141
  • 5
    Pardon my ignorance, but on the cycle counts, don't div and mul usually take more than one cycle? – Michael Myers May 20 '10 at 19:25
  • 3
    It depends on the CPU. On CPUs where div takes multiple cycles the numbers will be different but this algorithm is still the most efficient available. – Ray Burns May 20 '10 at 20:47
  • maybe using log() would be faster, see my solution – Tomas Aug 08 '11 at 11:22
  • 8
    Elric's answer is so much more elegant and probably faster too: `bool isPower3(uint32_t v) { return v != 0 && 3486784401u % v == 0; }`. Bragging about *Everyone seems to have missed the fastest algorithm of all* is usually ill-fated. – chqrlie Feb 28 '16 at 14:23
  • Division is always slow as it can't be optimized the way multiplication can, not even for much higher hardware costs. I've never heard about a CPU doing division in one cycle; on modern amd64 even multiplication takes 3-4 cycles and division is an *order of magnitude* slower. – maaartinus Jan 11 '17 at 03:30
30

This is a summary of all good answers below this questions, and the performance figures can be found from the LeetCode article.

1. Loop Iteration

Time complexity O(log(n)), space complexity O(1)

public boolean isPowerOfThree(int n) {
    if (n < 1) {
        return false;
    }

    while (n % 3 == 0) {
        n /= 3;
    }

    return n == 1;
}

2. Base Conversion

Convert the integer to a base 3 number, and check if it is written as a leading 1 followed by all 0. It is inspired by the solution to check if a number is power of 2 by doing n & (n - 1) == 0

Time complexity: O(log(n)) depending on language and compiler, space complexity: O(log(n))

public boolean isPowerOfThree(int n) {
    return Integer.toString(n, 3).matches("^10*$");
}

3. Mathematics

If n = 3^i, then i = log(n) / log(3), and thus comes to the solution

Time complexity: depending on language and compiler, space complexity: O(1)

public boolean isPowerOfThree(int n) {
    return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
}

4. Integer Limitations

Because 3^19 = 1162261467 is the largest power of 3 number fits in a 32 bit integer, thus we can do

Time complexity: O(1), space complexity: O(1)

public boolean isPowerOfThree(int n) {
    return n > 0 && 1162261467 % n == 0;
}

5. Integer Limitations with Set

The idea is similar to #4 but use a set to store all possible power of 3 numbers (from 3^0 to 3^19). It makes code more readable.

6. Recursive (C++11)

This solution is specific to C++11, using template meta programming so that complier will replace the call isPowerOf3<Your Input>::cValue with calculated result.

Time complexity: O(1), space complexity: O(1)

template<int N>
struct isPowerOf3 {
    static const bool cValue = (N % 3 == 0) && isPowerOf3<N / 3>::cValue;
};

template<>
struct isPowerOf3<0> {
    static const bool cValue = false;
};

template<>
struct isPowerOf3<1> {
    static const bool cValue = true;
};

int main() {
    cout<<isPowerOf3<1162261467>::cValue;
    return 0;
}
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
HaoCS
  • 582
  • 6
  • 9
  • (Just planting a link without summarising the crucial points is in direct violation of paragraph four of [How do I write a good answer?](http://stackoverflow.com/help/how-to-answer) - way to go to amass down-votes. (Likewise for code, especially uncommented code.)) – greybeard Mar 26 '17 at 07:35
  • @greybeard thanks for the comments and I'll update my answer – HaoCS Mar 27 '17 at 00:01
  • 1
    @HaoCS nice solution! How do you know that 3^19 is the highest number that can fit in 32-bit system? How about maximum power of 4, 5 and so on? – Papps Jul 19 '20 at 23:56
  • @HaoCS could you please share details on the third implementation. I am interested in part where you add epsilon to both sides of the equation, how did you come up with such trick? – noobsaibot Jun 29 '21 at 08:30
28

if (log n) / (log 3) is integral then n is a power of 3.

pauljwilliams
  • 19,079
  • 3
  • 51
  • 79
  • 30
    True in mathematical sense, not practical because of rounding errors. I checked that (log 3^40)/log(3^40-1)=1.0 on my machine. – Rafał Dowgird Nov 26 '09 at 16:52
  • 4
    Imho, this is too inefficent and imprecise, though mathematically correct. – Dario Nov 26 '09 at 17:03
  • 1
    you mean: "if (log n) / (log 3) is **integer** then n is a power of 3.", right? – Hengameh May 23 '15 at 11:20
  • Using log2 instead of log eliminates rounding errors. – phoad Aug 31 '16 at 06:43
  • 1
    @phoad: No, it does not. First, the log2 of every integer that is not a power of two is not exactly representable in binary floating-point, so any function to calculate its log2 must return a result with a rounding error. Second, the division introduces another rounding error. So evaluating `log2(n) / log2(3)` generally has three rounding errors. Third, math library functions such as `log2` are often not implemented with correct rounding, so they have additional rounding errors. – Eric Postpischil Jul 03 '19 at 11:32
  • 1
    for folks here saying there are rounding errors, use the log10 methods that account for floating point arithmetics out of the box. In javascript for instance, `Number.isInteger(Math.log10(n) / Math.log10(3))` – Farzad Yousefzadeh Feb 25 '21 at 21:49
11

Recursively divide by 3, check that the remainder is zero and re-apply to the quotient.

Note that 1 is a valid answer as 3 to the zero power is 1 is an edge case to beware.

JB King
  • 11,860
  • 4
  • 38
  • 49
  • 3
    +1 for the correct approach, but recursion (in its true sense) is completely unnecessary. This can be done iteratively. – Carl Smotricz Nov 26 '09 at 15:39
  • 7
    +1 @Carl Smotzicz: The algorithm is inherently recursive, iteration just a workaround with no objective advantage (see tail-recursion elimination) – Dario Nov 26 '09 at 15:51
  • 10
    Or, iterate the other way: -- is the number 1 (ie 3^0) ? if so, success if not continue: -- is the number 1*3, ... -- is the number 1*3*3 ... This avoids division and keeps your firmly in the realm of integers. OR, if you are using a system with, say, 64-bit integers, build a table of the powers of 3 and check against each entry in the array, it's only 40 elements. – High Performance Mark Nov 26 '09 at 15:53
11

Very interesting question, I like the answer from starblue, and this is a variation of his algorithm which will converge little bit faster to the solution:

private bool IsPow3(int n)
{
    if (n == 0) return false;
    while (n % 9 == 0)
    {
        n /= 9;
    }
    return (n == 1 || n == 3);
}
Community
  • 1
  • 1
user218447
  • 659
  • 5
  • 5
9

Between powers of two there is at most one power of three. So the following is a fast test:

  1. Find the binary logarithm of n by finding the position of the leading 1 bit in the number. This is very fast, as modern processors have a special instruction for that. (Otherwise you can do it by bit twiddling, see Bit Twiddling Hacks).

  2. Look up the potential power of three in a table indexed by this position and compare to n (if there is no power of three you can store any number with a different binary logarithm).

  3. If they are equal return yes, otherwise no.

The runtime depends mostly on the time needed for accessing the table entry. If we are using machine integers the table is small, and probably in cache (we are using it many millions of times, otherwise this level of optimization wouldn't make sense).

starblue
  • 55,348
  • 14
  • 97
  • 151
  • 1
    Storing zero there is a bad idea as then you'd have to ensure that zero does not get mapped to this slow. Storing there an arbitrary power of three works. I've just posted a different [perfect hashing based answer](http://stackoverflow.com/a/41582594/581205) and I see I could have used `numberOfLeadingZeros` as the hash. – maaartinus Jan 11 '17 at 04:25
  • @maaartinus Fixed it, but in a more general way. – starblue Jan 11 '17 at 19:59
  • That's correct, but my trivial initialization like `table = [1 for i in range(32)]` in my answer requires no thinking. And no thinking means no chance of thinking wrong. ;) – maaartinus Jan 12 '17 at 01:16
6

Here is a nice and fast implementation of Ray Burns' method in C:

bool is_power_of_3(unsigned x) {
    if (x > 0x0000ffff)
        x *= 0xb0cd1d99;    // multiplicative inverse of 59049
    if (x > 0x000000ff)
        x *= 0xd2b3183b;    // multiplicative inverse of 243
    return x <= 243 && ((x * 0x71c5) & 0x5145) == 0x5145;
}

It uses the multiplicative inverse trick for to first divide by 3^10 and then by 3^5. Finally, it needs to check whether the result is 1, 3, 9, 27, 81, or 243, which is done by some simple hashing that I found by trial-and-error.

On my CPU (Intel Sandy Bridge), it is quite fast, but not as fast as the method of starblue that uses the binary logarithm (which is implemented in hardware on that CPU). But on a CPU without such an instruction, or when lookup tables are undesirable, it might be an alternative.

Community
  • 1
  • 1
Falk Hüffner
  • 4,942
  • 19
  • 25
5

How large is your input? With O(log(N)) memory you can do faster, O(log(log(N)). Precompute the powers of 3 and then do a binary search on the precomputed values.

Alexandru
  • 25,070
  • 18
  • 69
  • 78
5

Simple and constant-time solution:

return n == power(3, round(log(n) / log(3)))
Tomas
  • 57,621
  • 49
  • 238
  • 373
4

For really large numbers n, you can use the following math trick to speed up the operation of

  n % 3 == 0

which is really slow and most likely the choke point of any algorithm that relies on repeated checking of remainders. You have to understand modular arithmetic to follow what I am doing, which is part of elementary number theory.

Let x = Σ k a k 2 k be the number of interest. We can let the upper bound of the sum be ∞ with the understanding that a k = 0 for some k > M. Then

0 ≡ x ≡ Σ k a k 2 k ≡ Σ k a 2k 2 2k + a 2k+1 2 2k+1 ≡ Σ k 2 2k ( a 2k + a 2k+1 2) ≡ Σ k a 2k + a 2k+1 2 (mod 3)

since 22k ≡ 4 k ≡ 1k ≡ 1 (mod 3).

Given a binary representation of a number x with 2n+1 bits as

x0 x1 x2 ... x2n+1

where xk ∈{0,1} you can group odd even pairs

(x0 x1) (x2 x3) ... (x2n x2n+1).

Let q denote the number of pairings of the form (1 0) and let r denote the number of pairings of the form (0 1). Then it follows from the equation above that 3 | x if and only if 3 | (q + 2r). Furthermore, you can show that 3|(q + 2r) if and only if q and r have the same remainder when divided by 3.

So an algorithm for determining whether a number is divisible by 3 could be done as follows

 q = 0, r = 0
 for i in {0,1, .., n}
     pair <- (x_{2i} x_{2i+1})
     if pair == (1 0)
         switch(q)
             case 0:
                 q = 1;
                 break;
             case 1:
                 q = 2;
                 break;
             case 2:
                 q = 0;
                 break;
     else if pair == (0 1)
         switch(r)
             case 0:
                 r = 1;
                 break;
             case 1:
                 r = 2;
                 break;
             case 2:
                 r = 0;
 return q == r

This algorithm is more efficient than the use of %.

--- Edit many years later ----

I took a few minutes to implement a rudimentary version of this in python that checks its true for all numbers up to 10^4. I include it below for reference. Obviously, to make use of this one would implement this as close to hardware as possible. This scanning technique can be extended to any number that one wants to by altering the derivation. I also conjecture the 'scanning' portion of the algorithm can be reformulated in a recursive O(log n) type formulation similar to a FFT, but I'd have to think on it.

#!/usr/bin/python

def bits2num(bits):
    num = 0
    for i,b in enumerate(bits):
        num += int(b) << i
    return num

def num2bits(num):
    base = 0
    bits = list()
    while True:
        op = 1 << base
        if op > num:
            break
        bits.append(op&num !=0)
        base += 1
    return "".join(map(str,map(int,bits)))[::-1]

def div3(bits):

    n = len(bits)

    if n % 2 != 0:
        bits = bits + '0'

    n = len(bits)

    assert n % 2 == 0

    q = 0
    r = 0
    for i in range(n/2):
        pair = bits[2*i:2*i+2]
        if pair == '10':
            if q == 0:
                q = 1
            elif q == 1:
                q = 2
            elif q == 2:
                q = 0
        elif pair == '01':
            if r == 0:
                r = 1
            elif r == 1:
                r = 2
            elif r == 2:
                r = 0
        else:
            pass

    return q == r

for i in range(10000):
    truth = (i % 3)  == 0
    bits = num2bits(i)
    check  = div3(bits)
    assert truth == check
ldog
  • 11,707
  • 10
  • 54
  • 70
  • What language is this? What's the time for one million (or one billion) executions of `x % 3` and the time for the same number of executions of this algorithm? – Chip Uni Nov 26 '09 at 22:29
  • % uses the euclidian algorithm which is a general algorithm to determine the remainder when dviding by an arbitriary number. % worst case (non-bitwise) time complexity is 5 times the number of digits in the base 10 representation of the smaller number, meaning no more than 15 multiplications and subtractions. This is O(n) in the complexity of the number of bits, however. – ldog Nov 26 '09 at 22:41
  • This is pseudo code, it can easily be implemented in C or C++ efficiently. Keep in mind that multiplication can not be done in O(n) time, so the euclidian algorithm will be slower than this. – ldog Nov 26 '09 at 22:49
  • 1
    I should rephrase that, we don't know of a multiplication algorithm that computes the product in O(n) time where n is the number of bits. – ldog Nov 26 '09 at 22:51
  • 1
    You're forgetting an important fact: hardware is much faster than software. As long as you have multiplication in hardware, % is going to be faster. Your algorithm could still be useful for a bignum library, though. – LaC Nov 26 '09 at 23:02
  • hmm yes, I agree that hardware is generally faster. I thought that the initial question was posed for cases where the input number is **very big** otherwise why bother? just create a look up tables up to the largest power of 3 you want to represent, the look up table will be of logarithmic size, and pretty compact. – ldog Nov 26 '09 at 23:09
  • This is just a test for divisibility by 3 by looking at the binary digits (similar to the test for divisibility by 11 for decimal numbers). In practice you would use bit twiddling to make it fast. – starblue Apr 27 '13 at 06:54
  • @starblue yea its exactly that but slightly more optimized for base 2. – ldog Mar 30 '17 at 01:41
3

You can do better than repeated division, which takes O(lg(X) * |division|) time. Essentially you do a binary search on powers of 3. Really we will be doing a binary search on N, where 3^N = input value). Setting the Pth binary digit of N corresponds to multiplying by 3^(2^P), and values of the form 3^(2^P) can be computed by repeated squaring.

Algorithm

  • Let the input value be X.
  • Generate a list L of repeated squared values which ends once you pass X.
  • Let your candidate value be T, initialized to 1.
  • For each E in reversed L, if T*E <= X then let T *= E.
  • Return T == X.

Complexity:

O(lg(lg(X)) * |multiplication|) - Generating and iterating over L takes lg(lg(X)) iterations, and multiplication is the most expensive operation in an iteration.

Craig Gidney
  • 17,763
  • 5
  • 68
  • 136
  • I am not sure this is better than repeated division in practice because a division-based solution short-circuits very quickly in the typical case. You can stop dividing once you get a remainder, which is after the very first pass on two-thirds of random input. 8/9 of random input requires no more than 2 passes; etc. Unless division is VASTLY slower than multiplication (which it typically isn't these days), the division method usually produces an answer before you have even finished generating L. – John Y Nov 26 '09 at 19:30
3

The fastest solution is either testing if n > 0 && 3**19 % n == 0 as given in another answer or perfect hashing (below). First I'm giving two multiplication-based solutions.

Multiplication

I wonder why everybody missed that multiplication is much faster than division:

for (int i=0, pow=1; i<=19, pow*=3; ++i) {
    if (pow >= n) {
        return pow == n;
    }
}
return false;

Just try all powers, stop when it grew too big. Avoid overflow as 3**19 = 0x4546B3DB is the biggest power fitting in signed 32-bit int.

Multiplication with binary search

Binary search could look like

int pow = 1;
int next = pow * 6561; // 3**8
if (n >= next) pow = next;
next = pow * 81; // 3**4
if (n >= next) pow = next;
next = pow * 81; // 3**4; REPEATED
if (n >= next) pow = next;
next = pow * 9; // 3**2
if (n >= next) pow = next;
next = pow * 3; // 3**1
if (n >= next) pow = next;
return pow == next;

One step is repeated, so that the maximum exponent 19 = 8+4+4+2+1 can exactly be reached.

Perfect hashing

There are 20 powers of three fitting into a signed 32-bit int, so we take a table of 32 elements. With some experimentation, I found the perfect hash function

def hash(x):
    return (x ^ (x>>1) ^ (x>>2)) & 31;

mapping each power to a distinct index between 0 and 31. The remaining stuff is trivial:

// Create a table and fill it with some power of three.
table = [1 for i in range(32)]
// Fill the buckets.
for n in range(20): table[hash(3**n)] = 3**n;

Now we have

table = [
     1162261467, 1, 3, 729, 14348907, 1, 1, 1,
     1, 1, 19683, 1, 2187, 81, 1594323, 9,
     27, 43046721, 129140163, 1, 1, 531441, 243, 59049,
     177147, 6561, 1, 4782969, 1, 1, 1, 387420489]

and can test very fast via

def isPowerOfThree(x):
    return table[hash(x)] == x
Community
  • 1
  • 1
maaartinus
  • 44,714
  • 32
  • 161
  • 320
  • You can combine division and multiplication: divide once, check for zero, repeatedly multiply&compare without overflow. – greybeard Jan 11 '17 at 07:10
  • 1
    `I wonder why everybody missed that multiplication is much faster than division` - [did everyone](http://stackoverflow.com/questions/1804311/how-to-check-if-an-integer-is-a-power-of-3/24274850#comment1692617_1804337)? – greybeard Jan 11 '17 at 08:12
  • @greybeard Combining division and multiplication sounds slow as even a single division is too costly. +++ I see I missed your comment. – maaartinus Jan 11 '17 at 10:14
  • 1
    `even a single division [sounds] costly` I _expect_ a compiler to convert division by a constant to multiplication if that is noticeably faster. – greybeard Jan 11 '17 at 10:35
1

Your question is fairly easy to answer by defining a simple function to run the check for you. The example implementation shown below is written in Python but should not be difficult to rewrite in other languages if needed. Unlike the last version of this answer, the code shown below is far more reliable.

Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import math
>>> def power_of(number, base):
    return number == base ** round(math.log(number, base))

>>> base = 3
>>> for power in range(21):
    number = base ** power
    print(f'{number} is '
          f'{"" if power_of(number, base) else "not "}'
          f'a power of {base}.')
    number += 1
    print(f'{number} is '
          f'{"" if power_of(number, base) else "not "}'
          f'a power of {base}.')
    print()


1 is a power of 3.
2 is not a power of 3.

3 is a power of 3.
4 is not a power of 3.

9 is a power of 3.
10 is not a power of 3.

27 is a power of 3.
28 is not a power of 3.

81 is a power of 3.
82 is not a power of 3.

243 is a power of 3.
244 is not a power of 3.

729 is a power of 3.
730 is not a power of 3.

2187 is a power of 3.
2188 is not a power of 3.

6561 is a power of 3.
6562 is not a power of 3.

19683 is a power of 3.
19684 is not a power of 3.

59049 is a power of 3.
59050 is not a power of 3.

177147 is a power of 3.
177148 is not a power of 3.

531441 is a power of 3.
531442 is not a power of 3.

1594323 is a power of 3.
1594324 is not a power of 3.

4782969 is a power of 3.
4782970 is not a power of 3.

14348907 is a power of 3.
14348908 is not a power of 3.

43046721 is a power of 3.
43046722 is not a power of 3.

129140163 is a power of 3.
129140164 is not a power of 3.

387420489 is a power of 3.
387420490 is not a power of 3.

1162261467 is a power of 3.
1162261468 is not a power of 3.

3486784401 is a power of 3.
3486784402 is not a power of 3.

>>> 

NOTE: The last revision has caused this answer to become nearly the same as TMS' answer.

Community
  • 1
  • 1
Noctis Skytower
  • 21,433
  • 16
  • 79
  • 117
  • Shouldn't there be a check that the number is a positive value, though? – JB King Nov 26 '09 at 15:34
  • You can also use: Math.Log(x, 3) == Math.Round(Math.Log(x, 3)) – Elisha Nov 26 '09 at 15:34
  • Surely he was asking for a bit hack? – int3 Nov 26 '09 at 15:37
  • 2
    Unless I'm very mistaken, this is a horribly stupid implementation. It's unlikely that Math.Log will evaluate to a number that's all 0's in the trailing decimals; in other words, it's very ignorant of floating-point rounding errors. – Carl Smotricz Nov 26 '09 at 15:38
  • 2
    just FYI >>> [((math.log(3**i) / math.log(3)) % 1 == 0) for i in range(20)] [True, True, True, True, True, False, True, True, True, True, False, True, True, False, True, False, True, False, True, True] – YOU Nov 26 '09 at 15:40
  • 1
    So the algorithm fails for 3^6, 3^11 and others. Thank you, S.Mark . I don't have a Python handy so I wasn't able to deliver this proof myself. – Carl Smotricz Nov 26 '09 at 15:49
  • 2
    Noctis, I apologize for sounding harsh, but I consider an algorithm unacceptable if it doesn't produce a correct result for all values of its defined input range. – Carl Smotricz Nov 26 '09 at 15:56
  • btw, if I rounded to around 5, its become more reasonable results, its surely rounding issues. >>> [(round((math.log(3**i)) / math.log(3),5) % 1 == 0) for i in range(20)] [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] – YOU Nov 26 '09 at 16:18
  • You know, "replace NUMBER with your number" etc. is nowadays usually expressed through functions with parameters. – Svante Nov 26 '09 at 16:28
  • @CarlSmotricz using `log10` instead of natural logartihm shoud work for 32-bit integer range (from [method 2](https://leetcode.com/discuss/78532/summary-all-solutions-new-method-included-at-15-30pm-jan-8th)). – TWiStErRob Jan 09 '16 at 19:19
0

Set based solution...

DECLARE @LastExponent smallint, @SearchCase decimal(38,0)

SELECT
    @LastExponent = 79, -- 38 for bigint
    @SearchCase = 729

;WITH CTE AS
(
    SELECT
        POWER(CAST(3 AS decimal(38,0)), ROW_NUMBER() OVER (ORDER BY c1.object_id)) AS Result,
        ROW_NUMBER() OVER (ORDER BY c1.object_id) AS Exponent
    FROM
        sys.columns c1, sys.columns c2
)
SELECT
    Result, Exponent
FROM
    CTE
WHERE
    Exponent <= @LastExponent
    AND
    Result = @SearchCase

With SET STATISTICS TIME ON it record the lowest possible, 1 millisecond.

gbn
  • 422,506
  • 82
  • 585
  • 676
  • Is needed the second table 'sys.columns c2'? Did you chosen to use sys.columns for speed reasons? – Nitai Bezerra Nov 26 '09 at 17:14
  • I used the cross join to make sure I get enough rows, and sys.columns because I know it has at least 40-50 rows. And it was the first one I thought of :-) – gbn Nov 26 '09 at 17:20
0

Another approach is to generate a table on compile time. The good thing is, that you can extend this to powers of 4, 5, 6, 7, whatever

template<std::size_t... Is>
struct seq
{  };

template<std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>
{  };

template<std::size_t... Is>
struct gen_seq<0, Is...> : seq<Is...>
{  };

template<std::size_t N>
struct PowersOfThreeTable
{
    std::size_t indexes[N];
    std::size_t values[N];

    static constexpr std::size_t size = N;
};

template<typename LambdaType, std::size_t... Is>
constexpr PowersOfThreeTable<sizeof...(Is)>
    generatePowersOfThreeTable(seq<Is...>, LambdaType evalFunc)
{
    return { {Is...}, {evalFunc(Is)...} };
}

template<std::size_t N, typename LambdaType>
constexpr PowersOfThreeTable<N> generatePowersOfThreeTable(LambdaType evalFunc)
{
    return generatePowersOfThreeTable(gen_seq<N>(), evalFunc);
}

template<std::size_t Base, std::size_t Exp>
struct Pow
{
    static constexpr std::size_t val = Base * Pow<Base, Exp-1ULL>::val;
};

template<std::size_t Base>
struct Pow<Base, 0ULL>
{
    static constexpr std::size_t val = 1ULL;
};

template<std::size_t Base>
struct Pow<Base, 1ULL>
{
    static constexpr std::size_t val = Base;
};

constexpr std::size_t tableFiller(std::size_t val)
{ 
    return Pow<3ULL, val>::val;
}

bool isPowerOfThree(std::size_t N)
{
    static constexpr unsigned tableSize = 41; //choosen by fair dice roll

    static constexpr PowersOfThreeTable<tableSize> table = 
            generatePowersOfThreeTable<tableSize>(tableFiller);

    for(auto a : table.values)
        if(a == N)
            return true;
    return false;
}
NaCl
  • 2,683
  • 2
  • 23
  • 37
0

I measured times (C#, Platform target x64) for some solutions.

using System;
class Program
{
    static void Main()
    {
        var sw = System.Diagnostics.Stopwatch.StartNew();
        for (uint n = ~0u; n > 0; n--) ;
        Console.WriteLine(sw.Elapsed);              // nada   1.1 s
        sw.Restart();
        for (uint n = ~0u; n > 0; n--) isPow3a(n);
        Console.WriteLine(sw.Elapsed);              // 3^20  17.3 s
        sw.Restart();
        for (uint n = ~0u; n > 0; n--) isPow3b(n);
        Console.WriteLine(sw.Elapsed);              // % /   10.6 s
        Console.Read();
    }

    static bool isPow3a(uint n)  // Elric
    {
        return n > 0 && 3486784401 % n == 0;
    }

    static bool isPow3b(uint n)  // starblue
    {
        if (n > 0) while (n % 3 == 0) n /= 3;
        return n == 1;
    }
}

Another way (of splitting hairs).

using System;
class Program
{
    static void Main()
    {
        Random rand = new Random(0); uint[] r = new uint[512];
        for (int i = 0; i < 512; i++)
            r[i] = (uint)(rand.Next(1 << 30)) << 2 | (uint)(rand.Next(4));
        var sw = System.Diagnostics.Stopwatch.StartNew();
        for (int i = 1 << 23; i > 0; i--)
            for (int j = 0; j < 512; j++) ;
        Console.WriteLine(sw.Elapsed);                    //   0.3 s
        sw.Restart();
        for (int i = 1 << 23; i > 0; i--)
            for (int j = 0; j < 512; j++) isPow3c(r[j]);
        Console.WriteLine(sw.Elapsed);                    //  10.6 s
        sw.Restart();
        for (int i = 1 << 23; i > 0; i--)
            for (int j = 0; j < 512; j++) isPow3b(r[j]);
        Console.WriteLine(sw.Elapsed);                    //   9.0 s
        Console.Read();
    }

    static bool isPow3c(uint n)
    { return (n & 1) > 0 && 3486784401 % n == 0; }

    static bool isPow3b(uint n)
    { if (n > 0) while (n % 3 == 0) n /= 3; return n == 1; }
}
P_P
  • 787
  • 7
  • 10
  • Please use the result of `isPow3x(uint n)` (`WriteLine()` suggests itself) and state compiler and flags used. – greybeard Apr 29 '18 at 19:09
  • `I (you) could use…` using the result of an instrumented function is not about getting to know the result, but keeping the compiler from "optimising" unknown parts out. – greybeard Apr 29 '18 at 22:36
  • Your comments are very useful, thanks. So when the result of an instrumented function is used, and it's not about getting to know it, pay attention to the fact that the compiler might optimize out unknown parts, take a look at the disassembly. – P_P Apr 30 '18 at 12:59
0

Python program to check whether the number is a POWER of 3 or not.

    def power(Num1):
        while Num1 % 3 == 0:
            Num1 /= 3
        return Num1 == 1


    Num1 = int(input("Enter a Number: "))
    print(power(Num1))
-1

Python solution

from math import floor
from math import log

def IsPowerOf3(number):
  p = int(floor(log(number) / log(3)))
  power_floor = pow(3, p)
  power_ceil = power_floor * 3
  if power_floor == number or power_ceil == number:
    return True
  return False

This is much faster than the simple divide by 3 solution.

Proof: 3 ^ p = number

p log(3) = log(number) (taking log both side)

p = log(number) / log(3)

-1

Here's a general algorithm for finding out if a number is a power of another number:

bool IsPowerOf(int n,int b)
{
    if (n > 1)
    {
        while (n % b == 0)
        {
            n /= b;
        }
    }
    return n == 1;
}
Hengameh
  • 892
  • 7
  • 12
-1
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int main()
{
     int n, power=0;
      cout<<"enter a number"<<endl;
      cin>>n;
  if (n>0){

     for(int i=0; i<=n; i++)
     {

         int r=n%3;

            n=n/3;
         if (r==0){
            power++;
         }

         else{
               cout<<"not exactly power of 3";
                return 0;

             }
     }

   }

         cout<<"the power is "<<power<<endl;
  }
6ZUN9
  • 1
  • 2
-1

This is a constant time method! Yes. O(1). For numbers of fixed length, say 32-bits.

Given that we need to check if an integer n is a power of 3, let us start thinking about this problem in terms of what information is already at hand.

1162261467 is the largest power of 3 that can fit into an Java int.
1162261467 = 3^19 + 0

The given n can be expressed as [(a power of 3) + (some x)]. I think it is fairly elementary to be able to prove that if x is 0(which happens iff n is a power of 3), 1162261467 % n = 0.

The general idea is that if X is some power of 3, X can be expressed as Y/3a, where a is some integer and X < Y. It follows the exact same principle for Y < X. The Y = X case is elementary.

So, to check if a given integer n is a power of three, check if n > 0 && 1162261467 % n == 0.

Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43
-2

Python:

return n > 0 and 1162261467 % n == 0

OR Calculate log:

lg = round(log(n,3))
return 3**lg == n

1st approach is faster than the second one.

Archit Pandey
  • 167
  • 1
  • 7
  • What does the first part add to [Elric's 2014 answer](https://stackoverflow.com/a/24274850/3789665) beyond using a language printing `False` for `n=3**42;print(1162261467 % n == 0)`? Or the second part to [this 2011 answer](https://stackoverflow.com/a/6981293/3789665)? – greybeard Apr 21 '21 at 15:11
  • just for information. Comparing both methods. Also, this is for 32-bit constraint. @greybeard – Archit Pandey Apr 23 '21 at 02:58