0

my unit test failed because of this, so I wonder if I am using the right datatype?

Reading the specs of the double I'd think it should be ok, but this is what's happening:

I'm reading a string from a file with value 0,0175 (comma as decimal sep.)

then I convert it to a double and then multiply it by 10000.

The function which does the multiply is this:

private static double? MultiplyBy10000(double? input)
        {
            if (!input.HasValue)
            {
                return null;
            }
            return input.Value*10000;
        }

next is from the immediate window:

input.Value
0.0175
input.Value*10000
175.00000000000003

And that is where my unit test fails, because I expect 175.

Is the double not accurate enough for this?

Checked other values too:

input.Value*1
0.0175
input.Value*10
0.17500000000000002
input.Value*100
1.7500000000000002
input.Value*1000
17.5
input.Value*10000
175.00000000000003

The weird thing is, I have 12 testcases 0,0155 0,0225 0,016 0,0175 0,0095 0,016 0,016 0,0225 0,0235 0,0265

and assert 4 of these, and the other 3 don't have this behaviour

Michel
  • 23,085
  • 46
  • 152
  • 242
  • Double fractions are binary fractions. 0.5 in decimal is 0.1 in binary 0.25 is 0.01, etc. 0.0175 is apparently not exactly a binary fraction (or at least not with 64 bits in total) – Manfred Radlwimmer Apr 28 '16 at 09:09

2 Answers2

5

Is the double not accurate enough for this?

No, doubles are floating point numbers, which are inaccurate by design. You can use decimal which is accurate and more suitable if you need exact numbers.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 1
    Thanks. That's a clear answer. Gonna change it. – Michel Apr 28 '16 at 09:12
  • 1
    All tests are green, thanks. – Michel Apr 28 '16 at 09:26
  • doubles are not inaccurate by design. decimals are not "more accurate" or "exact". The problem is you have too many fingers to be a good programmer. https://codeblog.jonskeet.uk/2009/11/02/omg-ponies-aka-humanity-epic-fail/ – Aron Apr 28 '16 at 10:07
1

Floating point numbers where the value to the right of the decimal point are not powers of 2 cannot be accurately represented. Although you've got what looks like 0.0175 there's actually more data there.

After you've scaled the number up use Math.Round to trim off date on the right off the decimal point.

Sean
  • 60,939
  • 11
  • 97
  • 136