Here is a table of the first 65 nonnegative powers of two (from 20 to 264):
n | 2n |
---|---|
0 | 1 |
1 | 2 |
2 | 4 |
3 | 8 |
4 | 16 |
5 | 32 |
6 | 64 |
7 | 128 |
8 | 256 |
9 | 512 |
10 | 1,024 |
11 | 2,048 |
12 | 4,096 |
13 | 8,192 |
14 | 16,384 |
15 | 32,768 |
16 | 65,536 |
17 | 131,072 |
18 | 262,144 |
19 | 524,288 |
20 | 1,048,576 |
21 | 2,097,152 |
22 | 4,194,304 |
23 | 8,388,608 |
24 | 16,777,216 |
25 | 33,554,432 |
26 | 67,108,864 |
27 | 134,217,728 |
28 | 268,435,456 |
29 | 536,870,912 |
30 | 1,073,741,824 |
31 | 2,147,483,648 |
32 | 4,294,967,296 |
33 | 8,589,934,592 |
34 | 17,179,869,184 |
35 | 34,359,738,368 |
36 | 68,719,476,736 |
37 | 137,438,953,472 |
38 | 274,877,906,944 |
39 | 549,755,813,888 |
40 | 1,099,511,627,776 |
41 | 2,199,023,255,552 |
42 | 4,398,046,511,104 |
43 | 8,796,093,022,208 |
44 | 17,592,186,044,416 |
45 | 35,184,372,088,832 |
46 | 70,368,744,177,664 |
47 | 140,737,488,355,328 |
48 | 281,474,976,710,656 |
49 | 562,949,953,421,312 |
50 | 1,125,899,906,842,624 |
51 | 2,251,799,813,685,248 |
52 | 4,503,599,627,370,496 |
53 | 9,007,199,254,740,992 |
54 | 18,014,398,509,481,984 |
55 | 36,028,797,018,963,968 |
56 | 72,057,594,037,927,936 |
57 | 144,115,188,075,855,872 |
58 | 288,230,376,151,711,744 |
59 | 576,460,752,303,423,488 |
60 | 1,152,921,504,606,846,976 |
61 | 2,305,843,009,213,693,952 |
62 | 4,611,686,018,427,387,904 |
63 | 9,223,372,036,854,775,808 |
64 | 18,446,744,073,709,551,616 |
With enough exposure to computers and binary numbers you will likely memorize 20 through 216.
Here’s the same table without commas in the numbers, to make it more convenient to copy and paste one into your code:
n | 2n |
---|---|
0 | 1 |
1 | 2 |
2 | 4 |
3 | 8 |
4 | 16 |
5 | 32 |
6 | 64 |
7 | 128 |
8 | 256 |
9 | 512 |
10 | 1024 |
11 | 2048 |
12 | 4096 |
13 | 8192 |
14 | 16384 |
15 | 32768 |
16 | 65536 |
17 | 131072 |
18 | 262144 |
19 | 524288 |
20 | 1048576 |
21 | 2097152 |
22 | 4194304 |
23 | 8388608 |
24 | 16777216 |
25 | 33554432 |
26 | 67108864 |
27 | 134217728 |
28 | 268435456 |
29 | 536870912 |
30 | 1073741824 |
31 | 2147483648 |
32 | 4294967296 |
33 | 8589934592 |
34 | 17179869184 |
35 | 34359738368 |
36 | 68719476736 |
37 | 137438953472 |
38 | 274877906944 |
39 | 549755813888 |
40 | 1099511627776 |
41 | 2199023255552 |
42 | 4398046511104 |
43 | 8796093022208 |
44 | 17592186044416 |
45 | 35184372088832 |
46 | 70368744177664 |
47 | 140737488355328 |
48 | 281474976710656 |
49 | 562949953421312 |
50 | 1125899906842624 |
51 | 2251799813685248 |
52 | 4503599627370496 |
53 | 9007199254740992 |
54 | 18014398509481984 |
55 | 36028797018963968 |
56 | 72057594037927936 |
57 | 144115188075855872 |
58 | 288230376151711744 |
59 | 576460752303423488 |
60 | 1152921504606846976 |
61 | 2305843009213693952 |
62 | 4611686018427387904 |
63 | 9223372036854775808 |
64 | 18446744073709551616 |
The constants 232 through 263 require 64-bit integers (264 won’t fit in a 64-bit integer). Here’s an example of how to use these large constants in a C program:
unsigned long long po2 = 9223372036854775808ULL; //2^63
The ‘long long’ declaration means 64-bit integer, and the ‘ULL’ suffix means an ‘unsigned long long’ constant.
[quote]
unsigned long long po2 = 9223372036854775808ULL; //2^63
[/quote]
Please don’t ever do that.
Use the left shift operator (<<) instead, like
unsigned long long po2 = 1ULL<<63;
@lallehat,
My method assigns a decimal power of two from the table directly to a variable. Your method assigns a power of two indirectly through knowledge of the underlying binary representation (two’s complement) and bit shifting operations. Both methods work: mine uses the “2n” column, and yours uses the “n” column. I would think it’s just a matter of personal preference as to which method you choose.
As for performance, there’s no difference. Both should be resolved at compile time. For example, under Visual C++, both resolve to these two assembler statements:
[quote] Your method assigns a power of two indirectly through knowledge of the underlying binary representation (two’s complement)[/quote]
No, the << operator (as most things in the C standard) is defined with what it does to the numeric values of its operands, diregarding the actual implementation.
Of course, as always with arithmetic in C, if you deal with unsigned integers the "overflow" is perfectly defined as modulo "TYPE_MAX", and if you deal with signed integers, you'll get an undefined behavior on overflow. The degree of undefinedness depends on the implementation, of course, but that's another story 🙂
@al,
I see your point, but what I meant was, to write “1ULL<<63”, you have to know that 263 is a 1 followed by 63 0s.