0

How can i calculate in C power of 2, without pow function?

For example, after keyboard input 4, the result to be 16?

I know that, for example, 2^5 can be typing similar like 2^1*2^5 (I don't know if this idea can help)

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Alexandru Cristian
  • 109
  • 1
  • 1
  • 5
  • 3
    Do you know how 2^N looks in binary? Do you know how to do bit shifting? Once you know both, you have your answer. – Eugene Sh. Mar 17 '21 at 13:45
  • Why would you use `pow()` for small integer powers anyway? – John Bollinger Mar 17 '21 at 13:45
  • 3
    You can perform multiplications in a loop, with varying degrees of cleverness, but for powers of 2 in particular, you should be looking into the bitwise left-shift operator (`<<`). – John Bollinger Mar 17 '21 at 13:47
  • 2
    A power of 2 can be found by shifting: 2-to-the-N is obtained from `1 << N`. For other bases an alternative to the brute-force multiplication loop is **exponentiation** as in [this answer](https://stackoverflow.com/a/213897/4142924). – Weather Vane Mar 17 '21 at 14:05
  • @WeatherVane *for other bases* which are not powers of 2 – Eugene Sh. Mar 17 '21 at 14:08
  • 1
    @EugeneSh. other bases which are not 2. OP asks "How can i calculate in C power of 2?" – Weather Vane Mar 17 '21 at 14:09
  • @WeatherVane I mean that 4^N can be calculated by shifting as well. – Eugene Sh. Mar 17 '21 at 14:10
  • Yes, but first you would have to figure out that it *is* a power of 2, when presented with the more general problem x-to-the-y. And by the time you did that, you might as well exponentiate. – Weather Vane Mar 17 '21 at 14:11

2 Answers2

4

To calculate 2N in C, use 1 << N.

If this may exceed the value representable in an int, use (Type) 1 << N, where Type is the integer type you want to use, such as unsigned long or uint64_t.

<< is the left-shift operator. It moves bits “left” in the bits that represent a number. Since numbers are represented in binary, moving bits left increases the powers of 2 they represent. Thus, 12 represents 1, 102 represents 2, 1002 represents 4, and so on, so 1 shifted left N positions represents 2N.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • How did a recursive function have more upvotes than this idiomatic solution is beyond me. Anyway, a side note for OP: always make sure `N >= 0` before shifting, as [shifting with a negative `N` is undefined behavior in C](https://stackoverflow.com/q/4945703/3889449). – Marco Bonelli Nov 27 '21 at 13:42
0

Numbers can be represented in binary form. For example, if integers are stored using 32 bits, 1 is stored like this:

00000000 00000000 00000000 00000001

And the value is the result of 1 x (20)

If you do a left-shift operation your value will be stored as this:

00000000 00000000 00000000 00000010

That means that now the result is result of 1 x (21)

Bit used to store a type is sizeof(type)x8, because a byte is 8 bit.

So best method is to use shift:

The left-shift of 1 by exp is equivalent to 2 raised to exp. Shift operators must not be used for negative exponents in case of pow. The result is an undefined behaviour. Another case of undefined behavior is the one of shifting the number equal to or more than N, in case of that number is stored in N bits.

#include <stdio.h>
#include <stdlib.h>

int main() {
    int exp;
    printf("Please, insert exponent:\n");
    if (scanf("%d", &exp) != 1) {
        printf("ERROR: scanf\n");
        exit(EXIT_FAILURE);
    }
    if (exp < 0) {
        printf("ERROR: exponent must be >= 0\n");
        exit(EXIT_FAILURE);
    }
    printf("2^(%d) = %d\n", exp, 1 << exp);
    exit(EXIT_SUCCESS);
}

You can also do it creating a ricorsive function (int) -> int:

int my_pow(int exp) {
    If (exp < 0 ) {
        return -1;
    }
    if (exp == 0) {
        return 1;
    }
    if (exp > 0) {
        return 2 * my_pow(exp-1);
    }
}

Using it as main:

int main() {    
    int exp;
    scanf("%d" &exp);
    int res = my_pow(exp);
        if (res == -1) {
            printf("ERROR: Exponent must be equal or bigger than 0\n");
            exit(EXIT_FAILURE);
        } 
        printf("2^(%d) = %d", exp, res);
    return 0;
}
ClaudioDeLise
  • 247
  • 1
  • 9
  • Probably because this answer gives a suboptimal solution to something that has an idiomatic optimal one. – Eugene Sh. Mar 17 '21 at 14:12
  • @EugeneSh. The answer was: "How can i calculate power of 2 in C without using function `pow()`?" I asked with two metods. – ClaudioDeLise Mar 17 '21 at 14:15
  • And as said, neither of them is the one we usually use in C. Anyway, I am not the downvoter, but I can relate. – Eugene Sh. Mar 17 '21 at 14:17
  • @EugeneSh. Do you agree with me when I say that the question asks for a method, not the best method neither the one usually used in C? – ClaudioDeLise Mar 17 '21 at 14:19
  • Not by me either, but neither code shows the typical shift that would be used. – Weather Vane Mar 17 '21 at 14:23
  • @WeatherVane And i understand it, but as i was saying. The answer asks for a method, not the best neither the typical one. – ClaudioDeLise Mar 17 '21 at 14:25
  • @ClaudioDeLise This site assumes high quality answers. Not lawyer answers. The algorithm as presented is not practical, and therefore not useful. And this is what the DV button is for. – Eugene Sh. Mar 17 '21 at 14:31
  • @EugeneSh. Ok, i got it. I edited my solution. I hope now is better, check for it, and thanks for the tips. – ClaudioDeLise Mar 17 '21 at 14:46
  • 1
    Please add an explanation of the bit shifting and this might become a good answer. Not sure if a downvoter will reverse the vote, but you might get other upvotes instead. – Eugene Sh. Mar 17 '21 at 14:48
  • @EugeneSh. I did, if you can please tell me if now is ok, and if you want to edit it there is no problems, thank you again! – ClaudioDeLise Mar 17 '21 at 15:09
  • @EricPostpischil You're right, i wanted to say for negative exponents, i'm going to edit it. – ClaudioDeLise Mar 17 '21 at 15:12
  • Re “Another case of undefined behavior is the one of shifting the number more than the size of integer,”: Equal to or more than. – Eric Postpischil Mar 17 '21 at 15:13
  • Re “integers are stored using 32 bits”: The numbers of bits in integer types are implementation-defined, subject to certain minimum bounds and other requirements. – Eric Postpischil Mar 17 '21 at 15:13
  • Not only is your recursive function going to take a lot longer, it doesn't handle the case of negative numbers at all - there's no `return` for that condition. – Mark Ransom Mar 17 '21 at 16:06
  • @MarkRansom because in the first main i check for negative numbers before using printf – ClaudioDeLise Mar 17 '21 at 16:15
  • 1
    It's still not a good idea to have a function with a path that allows it to reach the end without a return statement. – Mark Ransom Mar 17 '21 at 16:27
  • @MarkRansom You're right, i'm going to edit it! – ClaudioDeLise Mar 17 '21 at 16:29
  • Claudio, can you tell me if you are sure that is right : "Using it in main as: int res = my_pow(exp); if (res == -1) { printf("ERROR: Exponent must be equal or bigger than 0\n"); exit(EXIT_FAILURE); } printf("2^(%d) = %d", exp, res);"? – Alexandru Cristian Mar 18 '21 at 17:13
  • @AlexandruCristian Of course i am, if is not working, probably you are writing something wrong. If you prefer i write the entire main for the second method too. – ClaudioDeLise Mar 18 '21 at 17:16
  • So this "int res = my_pow(exp);" is not like int main()...? Cause in codeblocks i have error about main.c|13|error: 'exp' undeclared here (not in a function)| – Alexandru Cristian Mar 18 '21 at 17:33
  • @AlexandruCristian I edit the post and write a main for you, don't worry. – ClaudioDeLise Mar 18 '21 at 18:34