# The float, the finance and the folly

When I was studying mathematics in university, I was introduced to 3 number “lines”, for lack of a better word. They were the integers (denoted by Z with a double line at the slant), natural numbers (denoted by N with a double line at the slant) and real numbers (denoted by R with a double line at the vertical). There were others, such as complex numbers, rational and irrational numbers. Let’s keep this simple, shall we? Yeah, that’s how I wrote those symbols. I particularly like writing the Z with the 2 disconnected strokes. Ah, those times of writing mathematical proofs… To forestall a question you might have, the I is used to denote imaginary numbers, that’s why Z is used for integers. As to why Z is used for integers, Z

stands for Zahlen (German for numbers)

Integers (or whole numbers) are numbers without fractional parts, such as 5 or 72 or -3, including zero. Natural numbers are numbers for counting, referring to zero and positive integers (sometimes referred to as non-negative integers). Depending on context, zero might not be included. Real numbers are every single existing number available. Numbers such as 1.23456 and 3.14159 and 1.414. They also include integers, and naturally include the natural numbers.

Where am I going with this?

When I learned programming, the idea of having 2 sets of variable types dealing with numbers, one of integral types and one of non-integral types (which I gave a basic introduction here and here), was very natural. On the one hand, we have `byte`, `short`, `int` and `long`. On the other, we have `float` and `double`. I also learned the limitations of each variable type and the appropriate usage of each type.

You should be familiar with the integral types. It’s the non-integral types, or the floating points that I’m worried about. You will note that, while the integrals can’t represent all integers (they have a limit, like 2 ^ 31), they do represent the particular integer value exactly. A 100 is definitely a 100, for example (unless you change the form of representation).

The `float` and `double` variable types present a problem. They only hold a number value that’s close to the value you want (most of the time). It’s something about the IEEE representation, the mantissa and the exponent. Research on your own; it’s good for your learning.

Real numbers can have a precision stretching up to infinity. Obviously, our `float` and `double` have a bit of a problem with that. Actually this reminds me of a song I remembered from a children’s show (from way back when I was a child):

Thaaaaaaattt’ss iiiiinnnfinnnity
Yooouu can count forever
There’ll always be one more

That’s infinity
Count from dusk till dawn
You’ll never reach infinity
It’ll just go on, and on, and on, and on, and on…

You know, maybe I’ll sing and record it down… you know what? Maybe not. I’ll spare you the agony…

Ok, where was I? Oh yes, precision.

### Games don’t need it

More precisely, precision usually isn’t an issue in games. `float`s and `double`s are used in games for storing values such as the (x,y,z) positional coordinate of a player for instance. They don’t have to exact. They just have to be relatively close to the exact value. It’s not like you’re going to notice a 0.00000005 unit left shift, or you rotated like 0.000003 radians clockwise more than is required.

This is why `float`s are preferable to `double`s in games (I might be dated on this…), because they’re faster to add and multiply to, and you don’t need the extra precision.

### Financial applications depend on it

If you work with financial applications, it’s a whole new story. The Singapore and American currency use the dollar and cents. 100 cents equal a dollar. It’s typical to use \$12.34 to represent 12 dollars and 34 cents (my apologies to the comma-toting Europeans). So the dollar is correct (and exact) up to 2 decimal places.

Does anyone see a problem with using `float`s on this?

Sure, the `float` is more than capable of displaying just 2 decimal places. But it cannot represent the smallest unit of currency 0.01 exactly. To illustrate this, try the following piece of code:

```float f = 0f;
int i;
for (i = 0; i < 100; ++i)
{
f += 0.01f;
Console.WriteLine(f.ToString("f8"));
}
```

It's in C#, and you should be able to translate to C or some other language you use. Note the output. 0.01 is not 0.01 when stored in a floating point variable type.

This presents some exceedingly infuriating debugging sessions while figuring out why certain values don't work out correctly. It's also why you cannot do equality checks with floating point values (I mentioned this in my recent newsletter, and if you're not on it, please go sign up).

If you're using C# or some other modern language, there should be a variable type for fixed-point numbers (fixed number of digits after radix [or the decimal point]), the `decimal` type being the one for C#. Or the `numeric` data type in databases, but stay away from the `money` type. I don't know, I find it funny to store my monetary values in a money variable type. *shudder*

If you're using C or some other language without fixed-point number variable types, then my advice is to avoid calculation with floating points as much as possible. Do them in the environment where they are still exact.

For example, you want to retrieve some values from the database and bind them to local program variables. Then you're going to do some calculation with the variables, and update them back into the database. Can you do the calculation entirely in the database environment?

You might not have grasped the significance of the code above. Sure, the values are still exactly represented for most of the 100 decimal values. Imagine adding, subtracting, multiplying and dividing those values tens of times, hundreds of times. Ever heard of rounding errors? Errors don't disappear, they accumulate. If you're lucky, they cancel each other out. If not...

Here's a question for you. Even though it's a folly to represent the 2-decimal-point currency values with a floating point variable, there are values which a `float` can represent exactly. Given the range of non-negative 2-decimal-point values less than 1, what are the values that can be represented exactly?

1. Only quarters counted | Polymath Programmer

[…] week, at the end of the article, I presented a problem on floating point values: Given the range of non-negative 2-decimal-point values less than 1, what are the values that can […]

2. xavier sweeney

so where is the letter symbols for irrational numbers, irrational numbers, and whole numbers

i am an algebra student who was seeking this information

xavier sweeneys last blog post..How useful is wisdom of the crowd?

3. Vincent Tan

Hi xavier, I don’t think there’s a symbol for irrational numbers… Perhaps rational numbers are more useful? Rational numbers are denoted by Q. See this link for how it looks like:
http://friendfeed.com/e/d0335b1c-63e0-4f4a-b559-93da7a5ff967/How-I-write-my-set-of-rational-numbers-denoted-by/

And I don’t think there’s a symbol for whole numbers too. Perhaps you mean the set of integers Z?