0

I am doing following equation but the result is not as expected

   double dasdas = Math.Abs(3.2 - 1.9);

The result is

1.3000000000000003

However the correct result should be

1.3

What may be the reason of this?

c# 4.5.2

enter image description here

Furkan Gözükara
  • 22,964
  • 77
  • 205
  • 342
  • use `Math.Round(Math.Abs(3.2 - 1.9), 15);` if you want to keep the type as double. or keep `14` decimals instead of `15` to make it safer. – M.kazem Akhgary Nov 18 '15 at 11:12

2 Answers2

2

This is because you're using a double - which is a floating point. These by definition this cannot store the exact number.

You need to use Decimal.

Take at look at here and What Every Computer Scientist Should Read About Floating Point

Community
  • 1
  • 1
m.edmondson
  • 30,382
  • 27
  • 123
  • 206
  • 1
    decimal is also a floating point number and also cannot store the EXACT number, it just that it has base of 10 and will be fine keeping the sum result of two decimals precisely :) – mikus Nov 18 '15 at 11:03
  • Are you sure? The C Sharp Spec makes a distinction between floats and decimals see section 4.1.6 and 4.1.7 `"The decimal type has greater precision but smaller range than the floating-point types."` – m.edmondson Nov 18 '15 at 11:09
  • Floating points can store many numbers exactly. For example binary floating points can store `1.25` exactly, but not `1.1`. Decimal floating points (including the .net decimal type) can store `1.1` exactly but not `1/3`. – CodesInChaos Nov 18 '15 at 11:09
  • 1
    as a general rule, the same problem exists in Decimal – AK_ Nov 18 '15 at 11:10
  • 1
    well, if you read about how it's implementes you'll see that's exatly what it is... it has mantissa, exponent, and sign :P – mikus Nov 18 '15 at 11:10
  • Okay cool - so it's just fractional values it has trouble storing and despite documentation it's a float under the hood – m.edmondson Nov 18 '15 at 11:11
  • well I would say the specification is fairly clear about what is it, it's just this sentence that is a bit unprecise :) But yeap, they didnt really invent anything to go around this problem. It's just that decimal base is more suitable for many operations. – mikus Nov 18 '15 at 11:14
  • @mikus Indeed. For example, `Console.WriteLine(3m*(1m/3m));` will NOT print `1`. I'd say that `Decimal` is really intended for financial calculations, and would not be normally used for scientific or engineering calculation, particularly if performance is an issue. – Matthew Watson Nov 18 '15 at 11:16
1

Use decimal:

decimal dasdas = Math.Abs(3.2m - 1.9m);
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109