1

while trying to parse variable to float with following parameter float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out fValue),

the value=6666.77777 is rounded of to 6666.778.

can anyone help, i don't want my value to be rounded.

arjun sharma
  • 31
  • 1
  • 3
  • 3
    If you want to maintain *decimal* places, use a `decimal`. – Damien_The_Unbeliever Oct 23 '12 at 06:02
  • What do you want? An infinitely long string? – g t Oct 23 '12 at 06:02
  • Where do you see the value of `6666.778`? Probably the problem of the output format. But anyway you shall acknowledge that [floating points always have precision errors](http://stackoverflow.com/questions/753948/why-is-floating-point-arithmetic-in-c-sharp-imprecise). – Alvin Wong Oct 23 '12 at 06:02

4 Answers4

3

float only has around 6 significant digits. Note that digits before the decimal point count too. double has higher precision in that regard (around 16):

PS> [float]::Parse('6666,77777')
6666.778
PS> [double]::Parse('6666,77777')
6666.77777

But as others noted, this is just an approximate value because it cannot be represented exactly in base 2. If you need decimal exactness (e.g. for money values) then use a decimal. For most other things binary floating point (i.e. float and double) should be fine.

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

That is because value 666.77777 cannot be represented in the binary form floating point numbers use - the actual number contains more binary digits than the floating point has room for. The resulting number is the closest approximation.

Rounding is used when the exact result of a floating-point operation (or a conversion to floating-point format) would need more digits than there are digits in the significand. IEEE 754 requires correct rounding: that is, the rounded result is as if infinitely precise arithmetic was used to compute the value and then rounded (although in implementation only three extra bits are needed to ensure this). There are several different rounding schemes (or rounding modes). Historically, truncation was the typical approach. Since the introduction of IEEE 754, the default method (round to nearest, ties to even, sometimes called Banker's Rounding) is more commonly used.

You should consider using double if you need more precision, or decimal if you need even more than that, though they too suffer from precision loss at some point.

neeKo
  • 4,280
  • 23
  • 31
  • That's not the reason here :-). It *is* rounding. – Joey Oct 23 '12 at 06:04
  • It *appears* to be rounding, but actually it is not ;) – neeKo Oct 23 '12 at 06:07
  • See my answer. `float` just doesn't have enough significant digits to deal with that number. So the ones that don't fit are cut (rounded) off. This is completely orthogonal to the issue that binary floating point cannot represent some (most) numbers exactly. – Joey Oct 23 '12 at 06:08
  • You are correct. I guess I was taught outdated information - that it was truncated, not rounded. – neeKo Oct 23 '12 at 06:29
1

Why don't you use Double.TryParse or Decimal.TryParse to support higher precision:

float: Approximately ±1.5 x 10-45 to ±3.4 x 1038 with 7 significant figures

double: Approximately ±5.0 x 10-324 to ±1.7 x 10308 with 15 or 16 significant figures

decimal: Approximately ±1.0 x 10-28 to ±7.9 x 1028 with 28 or 29 significant figures

Try this piece of code snippet instead:

double fValue;
double.TryParse("6666.77777", NumberStyles.Double, CultureInfo.InvariantCulture, out fValue);

OR

decimal fValue;
decimal.TryParse("6666.77777", NumberStyles.Decimal, CultureInfo.InvariantCulture, out fValue);
Community
  • 1
  • 1
Furqan Safdar
  • 16,260
  • 13
  • 59
  • 93
0

you should use decimal if you need higher precision.

Mayank
  • 8,777
  • 4
  • 35
  • 60