CodeGym /Courses /C# SELF /Precision Issues and Special Values

Precision Issues and Special Values

C# SELF
Level 6 , Lesson 3
Available

1. Introduction

It seems like if a computer is "smart," then 0.1 + 0.2 should just be 0.3. But that's not exactly how it works. Let's break it down with a simple example.

double x = 0.1;
double y = 0.2;
double sum = x + y;
Console.WriteLine(sum); // What will the program print?
Adding floating-point numbers: we expect 0.3, but what do we actually get?

Now try comparing it to 0.3:

Console.WriteLine(sum == 0.3); // Will this be true or false?

If you see False, don't be surprised!

The reason is how numbers are stored in memory

Computers work with numbers in binary. But not all decimal fractions can be represented as a finite binary fraction, just like 1/3 can't be written exactly as a decimal (0.333...). For example, 0.1 in binary is an infinite fraction, so it has to be "rounded" to fit in memory.

To put it in plain English, double sometimes "pretends" to store your number exactly, but it's actually just holding a really close approximation.

2. What kind of "weirdness" can happen with double arithmetic?

Let's check out some real-life examples.

Example 1. The classic "magic" of 0.1 + 0.2

double a = 0.1;
double b = 0.2;
double sum = a + b;
Console.WriteLine(sum);            // 0.30000000000000004
Console.WriteLine(sum == 0.3);     // False

The computer didn't print 0.3, but 0.30000000000000004. The difference is tiny, but if you're working with, say, finances — that's a big deal.

Example 2. Iterative addition

double result = 0;
for (int i = 0; i < 10; i++)
{
    result += 0.1;
}
Console.WriteLine(result); // 0.9999999999999999

You wanted 1.0 — but you got just a bit less. Again, it's all about rounding inside double.

Why this matters in real-world tasks

A lot of people think: "Who cares, it's just a tiny error, whatever!" Let's look at an example from the world of payments.

Say your online bank adds up 100 transactions of 0.1 euro each. If your program "loses" one hundred-thousandth of a euro on every iteration, at the scale of a bank you're "losing" real money. That's when the accountant will come to you and ask: "Where's our money?!"

3. How to properly compare floating-point numbers

Since double often can't store exactly the value you expect, comparing directly with == can let you down. Instead, it's common to compare the absolute difference between numbers with some really tiny number (epsilon).

Example: comparing with a tolerance

double a = 0.1 + 0.2;
double b = 0.3;
double epsilon = 0.000001;

if (Math.Abs(a - b) < epsilon)
{
    Console.WriteLine("Almost equal!"); // This is a safer way to compare
}

Here we're saying: "If the difference between the numbers is less than one millionth, let's call them equal."

4. Special double values: Infinity, NaN, -Infinity

The double type stores not just numbers, but also some special values. These pop up in situations that any math teacher would totally forbid.

Infinity (Infinity)

What happens if you divide 1 by 0?

double result = 1.0 / 0.0;
Console.WriteLine(result); // Infinity

In C# (and lots of other languages), dividing by 0 for double doesn't throw an exception! Instead, the result becomes a special value called "positive infinity."

Negative infinity (-Infinity)

If you divide a negative number by 0, you get negative infinity:

double result = -1.0 / 0.0;
Console.WriteLine(result); // -Infinity

"Not a Number" (NaN — Not a Number)

If you do something really weird, like try to take the square root of a negative number:

double result = Math.Sqrt(-1);
Console.WriteLine(result); // NaN

Or the result of dividing 0.0 / 0.0:

double result = 0.0 / 0.0;
Console.WriteLine(result); // NaN

NaN — that's "anything that wouldn't be a number in real life."

Checking for special values

C# has functions to check for special values:

Console.WriteLine(double.IsInfinity(result));    // true if it's infinity
Console.WriteLine(double.IsNaN(result));         // true if it's NaN

Table: How double reacts to unusual operations

Operation Result What gets stored in double
1.0 / 0.0
Infinity +∞
-1.0 / 0.0
-Infinity -∞
0.0 / 0.0
NaN Not a number
Math.Sqrt(-1)
NaN Not a number
2
Task
C# SELF, level 6, lesson 3
Locked
Difference in Arithmetic Precision
Difference in Arithmetic Precision
2
Task
C# SELF, level 6, lesson 3
Locked
Comparison using epsilon
Comparison using epsilon
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION