## When Doubles Don’t Behave Like Doubles

In my article “When Floats Don’t Behave Like Floats” I explained how calculations involving single-precision floating-point variables may be done, under the covers, in double or extended precision. This leads to anomalies in expected results, which I demonstrated with two C programs — compiled with Microsoft Visual C++ and run on a 32-bit Intel Core Duo processor.

In this article, I’ll do a similar analysis for double-precision floating-point variables, showing how similar anomalies arise when extended precision calculations are done. I modified my two example programs to use doubles instead of floats. Interestingly, the doubles version of program 2 does not exhibit the anomaly. I’ll explain.

## When Floats Don’t Behave Like Floats

These two programs — compiled with Microsoft Visual C++ and run on a 32-bit Intel Core Duo processor — demonstrate an anomaly that occurs when using single-precision floating point variables:

Program 1

#include "stdio.h"
int main (void)
{
float f1 = 0.1f, f2 = 3.0f, f3;

f3 = f1 * f2;
if (f3 != f1 * f2)
printf("Not equal\n");
}


Prints “Not equal”.

Program 2

#include "stdio.h"
int main (void)
{
float f1 = 0.7f, f2 = 10.0f, f3;
int i1, i2;

f3 = f1 * f2;
i1 = (int)f3;
i2 = (int)(f1 * f2);
if (i1 != i2)
printf("Not equal\n");
}


Prints “Not equal”.

In each case, f3 and f1 * f2 differ. But why? I’ll explain what’s going on.

## Seeing Powers of Five in Powers of Two and Vice Versa

The decimal representations of oppositely signed powers of two and powers of five look alike, as seen in these examples: 2-3 = 0.125 and 53 = 125; 5-5 = 0.00032 and 25 = 32. The significant digits in each pair of powers is the same, even though one is a fraction and one is an integer. In other words, a negative power of one base looks like a positive power of the other.

This relationship is not coincidence; it’s a by-product of how fractions are represented as decimals. I’ll show you simple algebra that proves it, as well as algebra that proves similar properties — in products involving negative powers.

## Exploring Binary Numbers With PARI/GP Calculator

PARI/GP is an open source computer algebra system I use frequently in my study of binary numbers. It doesn’t manipulate binary numbers directly — input, and most output, is in decimal — so I use it mainly to do the next best thing: calculate with powers of two. Calculations with powers of two are, indirectly, calculations with binary numbers.

PARI/GP is a sophisticated tool, with several components — yet it’s easy to install and use. I use its command shell in particular, the PARI/GP calculator, or gp for short. I will show you how to use simple gp commands to explore binary numbers.

## A Simple C Program That Prints 2,098 Powers of Two

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!

## Print Precision of Dyadic Fractions Varies by Language

Interestingly, programming languages vary in how much precision they allow in printed floating-point fractions. You would think they’d all be the same, allowing you to print as many decimal places as you ask for. After all, a floating-point fraction is a dyadic fraction; it has as many decimal places as it has bits in its fractional representation.

Consider the dyadic fraction 5,404,319,552,844,595/253. Its decimal expansion is 0.59999999999999997779553950749686919152736663818359375, and its binary expansion is 0.10011001100110011001100110011001100110011001100110011. Both are 53 digits long. The ideal programming language lets you print all 53 decimal places, because all are meaningful. Unfortunately, many languages won’t let you do that; they typically cap the number of decimal places at between 15 and 17, which for our example might be 0.59999999999999998.

## The Powers of Two

The following infinite set of numbers is known as the powers of two:

.

Why are they called powers of two? What is the pattern you see? How is the set described mathematically? What are the set’s components? We will answer those questions in this article.

## Nonstandard Names for The Powers of Two

Now that you know how the powers of two are named, lets look at other, nonstandard ways to name them. You will see these names on the internet as well as in books. We will not use them on this site other than in this article, and we only discuss them here to make you aware of their use. As a by-product of this discussion, you may gain some insight into the nature of the powers of two. But beware — you may become confused as well!

## How to Check If a Number Is a Power of Two

How can you tell if a number is a power of two?

That’s easy if it’s in the form 2n, where n is an integer. For example, 212, 20, and 2-37 are powers of two. That is by definition. But what about arbitrary positive numbers like 16,392, 524,288, or 0.00390625? Are they powers of two? Here’s how to tell — if they can be simplified to the form 2n, they are; if they can’t, they’re not.