-2

First I noticed that Math.Round() doesn't round for 2 digits as I as for:

double dd = Math.Round(1.66666, 2);

Result:

dd = 1.6699999570846558;

and then I created a new project with same .NET framework and the result is 1.67 now as it should been in the first place.

I've never seen Round behaving like this before, what is causing this problem?

rae1
  • 6,066
  • 4
  • 27
  • 48
Igor Meszaros
  • 2,081
  • 2
  • 22
  • 46
  • 15
    Not this question again. [Please read the following](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – user703016 Mar 20 '14 at 13:25
  • The problem is you are using an imprecise numerical type to represent an exact value. If you want exact decimal values, use `decimal`. For a minute there I almost thought this was going to be the old "Banker's Rounding" issue. – Adam Houldsworth Mar 20 '14 at 13:28
  • double? The fact that you, as a prorammer, have avoided learning how floating point numbers work. WHich means you lack a fundamental understanding what you do - much like a cook wondering that the oven gets hot when he turns it on. – TomTom Mar 20 '14 at 13:28
  • Floating-point numbers get rounded off to... floating point numbers. Either live with that fact and display the number in an appropriate format, or use the `decimal` type. – Cᴏʀʏ Mar 20 '14 at 13:28
  • 2
    Or for a more easily accessible version of the sort of info at @presiuslitelsnoflek's link, see http://floating-point-gui.de/ – Tim S. Mar 20 '14 at 13:28
  • I'm sorry I couldn't find this question asked previously here... – Igor Meszaros Mar 20 '14 at 13:29

1 Answers1

3

Like the other comments mentioned, use decimal to hold the returned value:

decimal dd = Math.Round(1.66666M, 2);

The issue you described has nothing to do with the Round() function. You can read a bit about how the floating point numbers & fixed point numbers work, but the short explanation is:

With floating point variables (e.g. double), you cannot guarantee the precision of the number you save it them. So when you save something like 1.67 in a variable of the type double and then you check the value later on, therer is no guarantee you will get exactly 1.67. You may get a value like 1.66999999 (similar to what you got) or like 1.6700000001.

Fixed point variables (e.g. decimal) on the other hand, will give you that precision, so if you save 1.67, you will always get 1.67 back.

Please note that the Round() function returns the same type that you pass to it, so to make return a decimal, you need to pass it 1.66666M which is a decimal value rather than 1.66666 which is a floating point number.

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
  • @Weston Thanks for the observation. I was focused on the explanation rather than the code, because it was obvious that the OP was just testing things and he needed an explanation rather than code. I updated my answer, though, just for the sake of correctness. And I added a note about the `Round()` function. – Racil Hilan Mar 20 '14 at 13:59
  • Your answer was exactly what I was looking for, thank you! – Igor Meszaros Mar 20 '14 at 14:35