9

I have a problem rounding a float value. I have a float value that is set 0.8 but in the c# code it is somehow 0.80000000000000004.

So i want to round it so it becomes 0.8.

i have tried:

float roundedFloatvalue = (float)Math.Round((Decimal)floatvalue, 2, MidpointRounding.AwayFromZero);

and:

float roundedFloatvalue = Truncate(floatvalue, 2);

public static float Truncate(float value, int digits)
{
    double mult = Math.Pow(10.0, digits);
    double result = Math.Truncate(mult * value) / mult;
    return (float)result;
}

It just seems that i cant get 0.80000000000000004 to be 0.8 and i dont know why any of the above doesnt work.

Diemauerdk
  • 5,238
  • 9
  • 40
  • 56
  • 5
    Do you care about a `0.00000000000000004` difference? Anyway, read this: http://floating-point-gui.de/ – Blorgbeard Jan 07 '14 at 10:00
  • possible duplicate of [Why can't decimal numbers be represented exactly in binary?](http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary) – dan04 Jan 07 '14 at 20:17

3 Answers3

23

You cannot express 0.8 exactly as a binary floating point value since 0.8 is not representable in binary floating point. Required reading on this topic is What Every Computer Scientist Should Know About Floating-Point Arithmetic.

You might use decimal instead, which represents numbers using decimal floating point and can represent 0.8 exactly. Or you might choose to continue using binary floating point, but only display limited numbers of digits after the decimal point.

To get the value into a decimal variable, rounded to two decimal places, you write:

decimal decimalValue = Math.Round((decimal)floatValue, 2);
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
3

This is because there is no representation of a float that is exactly 0.8. You could use decimal instead, which is a decimal floating-point type instead of a binary floating-point type, or you could just format the number appropriately when displaying it.

Joey
  • 344,408
  • 85
  • 689
  • 683
2

Usually, you don't need to round floating point value when computing:

0.80000000000000004 is very close to 0.8

(if 0.0...04 is significant why do you use float, not double?)

The place you want to round up the value is the final output; in that case you can use formatting:

  float x = 0.80000000000000004F;
  Console.Write(x.ToString("G1")); // or "F1"
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 3
    It's not only very close, it's the closest IEEE 754 double precision to 8./10 (well, the closest is exactly 0.8000000000000000444089209850062616169452667236328125 but both would be rounded to same double precision float) – aka.nice Jan 07 '14 at 17:23