To write a computer program to print the first 1000 nonnegative powers of two, do you think you’d need to use arbitrary precision arithmetic? After all, 21000 is a 302-digit number. How about printing the first 1000 negative powers of two? 2-1000 weighs in at a whopping 1000 decimal places. It turns out all you need is standard double-precision floating-point arithmetic — and the right compiler!
You can write a simple program to print over 2000 powers of two — 2,098 to be exact — just by using one double-precision floating-point variable, or double. A double can hold 2,098 powers of two: 1,024 nonnegative powers of two, from 20 to 21023, and 1,074 negative powers of two, from 2-1 to 2-1074. The trick is to find a programming language that lets you print them all; GCC C on Linux is one such language. Here’s the program I wrote to do it:
/**********************************************************/ /* PO2Tables.c: A program that prints 2,098 powers of two */ /* */ /* Rick Regan, https://www.exploringbinary.com */ /* */ /* 1. Compile: gcc PO2Tables.c -o PO2Tables */ /* 2. Run: ./PO2Tables > PO2Tables.txt */ /* */ /**********************************************************/ #include <stdio.h> #include <math.h> #define NUM_NEGATIVE_PO2s 1074 /* -1 to -1074*/ #define NUM_NONNEGATIVE_PO2s 1024 /* 0 to 1023 */ void print_negative_PO2s () { unsigned int i; double po2 = 0.5; printf ("Negative Powers of Two\n"); printf ("======================\n"); for (i=1; i<=NUM_NEGATIVE_PO2s; i++) { printf ("2^-%d: %1.*f\n",i,i,po2); po2 /= 2; } } void print_nonnegative_PO2s () { unsigned int i; double po2 = 1; printf ("Nonnegative Powers of Two\n"); printf ("========================\n"); for (i=1; i<=NUM_NONNEGATIVE_PO2s; i++) { printf ("2^%d: %.0f\n",i-1,po2); po2 *= 2; } } int main(int argc, char *argv[]) { print_negative_PO2s(); printf ("\n"); print_nonnegative_PO2s(); return (0); }
The powers of two in each case are generated incrementally. The nonnegative powers of two are generated by repeated multiplication by 2, and the negative powers of two are generated by repeated division by 2. The printf() statement for the negative powers of two includes a parameter to specify the number of digits to print, which is simply the absolute value of the negative powers of two’s exponent.
Sample Output
Here is some sample output:
Negative Powers of Two ====================== 2^-1: 0.5 2^-2: 0.25 2^-3: 0.125 2^-4: 0.0625 2^-5: 0.03125 2^-6: 0.015625 2^-7: 0.0078125 2^-8: 0.00390625 . . . 2^-50: 0.00000000000000088817841970012523233890533447265625 2^-51: 0.000000000000000444089209850062616169452667236328125 2^-52: 0.0000000000000002220446049250313080847263336181640625 2^-53: 0.00000000000000011102230246251565404236316680908203125 2^-54: 0.000000000000000055511151231257827021181583404541015625 2^-55: 0.0000000000000000277555756156289135105907917022705078125 . . . Nonnegative Powers of Two ======================== 2^0: 1 2^1: 2 2^2: 4 2^3: 8 2^4: 16 2^5: 32 2^6: 64 2^7: 128 2^8: 256 . . . 2^182: 6129982163463555433433388108601236734474956488734408704 2^183: 12259964326927110866866776217202473468949912977468817408 2^184: 24519928653854221733733552434404946937899825954937634816 2^185: 49039857307708443467467104868809893875799651909875269632 2^186: 98079714615416886934934209737619787751599303819750539264 2^187: 196159429230833773869868419475239575503198607639501078528 . . .
Other Compilers
You can run this program on other compilers, but you’ll have to adjust the two #defines to keep within that compiler’s printing precision limits. For example, to compile this with Visual C++ to run on Windows, change the defines as follows:
#define NUM_NEGATIVE_PO2s 24 /* -1 to -24*/ #define NUM_NONNEGATIVE_PO2s 57 /* 0 to 56 */
Of course this prints much smaller tables — only 81 powers of two in total.
If you use Visual C++ but don’t change the constants, the program will run, but most of the printed powers of two will have 0s in place of their real digits.
i’ve try your code and work so fast…i really appreciate,
but this answer when define NUM_NONNEGATIVE_PO2s >=32
#define NUM_NONNEGATIVE_PO2s 32 /* 0 to 31 */ (32 up to MAX)
is return only a half digits of the answer has matching with your output,
i.e
when you 2^185=49039857307708443467467104868809893875799651909875269632
in my pc has return 49039857307708443000000000000000000000000000000000000000
why my pc has return only this value?
ikilobo,
Make sure to read the section above called “Other Compilers” and to read the articles I linked to in the introduction. That should give you your answer (if not, write back).
What compiler are you using?
Great, simple program. Excellent work.