-1

I'm writing an application where I need to handle mm and inches. I've written some simple code to scale between the two units of measure and I also have some code to take a decimal number and convert this to a fraction. However when I split the whole number from the decimal using Math.Floor I find I do not always get the expected value returned. I've attached some code to demonstrate the problem. I expect the final result to be 6 but I get 5. I'm struggling to understand why. Any ideas?

// This is a .Net 4.5 console application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            double ValA = 6;
            double ValB = 0;
            double ValC = 0;
            double ValD = 0;

            ValB = ValA * 25.4;

            ValC = ValB / 25.4; 

            ValD = Math.Floor(ValC);

            Console.WriteLine(ValA.ToString());
            Console.WriteLine(ValB.ToString());
            Console.WriteLine(ValC.ToString()); // This returns 6 as expected
            Console.WriteLine(ValD.ToString()); // But this returns 5.

            Console.ReadKey();
        }
    }
}
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
ChrisUK
  • 33

2 Answers2

6

Doubles are not exact representations of decimal numbers, they're represented with a binary base. They don't convert exactly to decimal numbers, so you have no guarantee that 5 * 2.52 / 2.52 will equal 5.0. I suggest using the C# type Decimal instead.

EDIT

See this question for more information about the C# Decimal type

Community
  • 1
  • 1
Jack
  • 2,223
  • 13
  • 23
2

The printout from this line

Console.WriteLine(ValC.ToString());

is misleading: I/O library prints 6, even though the actual value is slightly less than 6:

Console.WriteLine(ValC < 6.0);

the line above prints True, which makes sense: a tiny error accumulated after multiplying and dividing by the same number gets in the way.

According to IEEE-754 calculator, 25.4 is represented as 25.399999618530273. After multiplication and division, there is a tiny difference that amounts to about 8E-16, but the value that you get is slightly less than 6. That is why Floor correctly returns 5.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523