Math.Round..What am I missing?
-
I need to programatically convert float values like 17.1054688 to 17.11 in C# i.e want to restrict the float values upto 2 decimals. For this I have written following code:
private void Roundupto2Decimals(ref float fVal) { string strVal = fVal.ToString("F2"); fVal = float.Parse(strVal); double dVal = (double)fVal; }
In VS2005 watch window, I get the correct value for fVal. for e.g: Input : 17.1054688 strVal: "17.11" fVal : 17.11 but ---> (double)fVal : 17.110000610351563 I am not sure when I typecast the same float to double I get unepcted value. I expect dVal to be 17.11 too. Can any one help me understand what is happening? Thanks and Regards, Arti Gujare -
I need to programatically convert float values like 17.1054688 to 17.11 in C# i.e want to restrict the float values upto 2 decimals. For this I have written following code:
private void Roundupto2Decimals(ref float fVal) { string strVal = fVal.ToString("F2"); fVal = float.Parse(strVal); double dVal = (double)fVal; }
In VS2005 watch window, I get the correct value for fVal. for e.g: Input : 17.1054688 strVal: "17.11" fVal : 17.11 but ---> (double)fVal : 17.110000610351563 I am not sure when I typecast the same float to double I get unepcted value. I expect dVal to be 17.11 too. Can any one help me understand what is happening? Thanks and Regards, Arti Gujare -
I need to programatically convert float values like 17.1054688 to 17.11 in C# i.e want to restrict the float values upto 2 decimals. For this I have written following code:
private void Roundupto2Decimals(ref float fVal) { string strVal = fVal.ToString("F2"); fVal = float.Parse(strVal); double dVal = (double)fVal; }
In VS2005 watch window, I get the correct value for fVal. for e.g: Input : 17.1054688 strVal: "17.11" fVal : 17.11 but ---> (double)fVal : 17.110000610351563 I am not sure when I typecast the same float to double I get unepcted value. I expect dVal to be 17.11 too. Can any one help me understand what is happening? Thanks and Regards, Arti GujareIt's all due to the way floating point numbers are represented - some numbers can't be represented exactly, so will have very tiny errors. As suggested by the other poster, if you are using small numbers, and require high precision, then the Decimal type would be more suitable.
-- Help me! I'm turning into a grapefruit! Buzzwords!
-
It's all due to the way floating point numbers are represented - some numbers can't be represented exactly, so will have very tiny errors. As suggested by the other poster, if you are using small numbers, and require high precision, then the Decimal type would be more suitable.
-- Help me! I'm turning into a grapefruit! Buzzwords!
-
I need to programatically convert float values like 17.1054688 to 17.11 in C# i.e want to restrict the float values upto 2 decimals. For this I have written following code:
private void Roundupto2Decimals(ref float fVal) { string strVal = fVal.ToString("F2"); fVal = float.Parse(strVal); double dVal = (double)fVal; }
In VS2005 watch window, I get the correct value for fVal. for e.g: Input : 17.1054688 strVal: "17.11" fVal : 17.11 but ---> (double)fVal : 17.110000610351563 I am not sure when I typecast the same float to double I get unepcted value. I expect dVal to be 17.11 too. Can any one help me understand what is happening? Thanks and Regards, Arti Gujare -
I need to programatically convert float values like 17.1054688 to 17.11 in C# i.e want to restrict the float values upto 2 decimals. For this I have written following code:
private void Roundupto2Decimals(ref float fVal) { string strVal = fVal.ToString("F2"); fVal = float.Parse(strVal); double dVal = (double)fVal; }
In VS2005 watch window, I get the correct value for fVal. for e.g: Input : 17.1054688 strVal: "17.11" fVal : 17.11 but ---> (double)fVal : 17.110000610351563 I am not sure when I typecast the same float to double I get unepcted value. I expect dVal to be 17.11 too. Can any one help me understand what is happening? Thanks and Regards, Arti Gujarehello, math.round donot support float, its argument must be Double. for example : Double dblValue = 123.126789; dblValue = Math.Round(dblValue, 2); MessageBox.Show(dblValue.ToString());// Displays 123.13 I think u can continue your work. Best of Luck. :-O
Dipak
-
I tried with decimal too. Did not help much.. This is what I tried.
private void Roundupto2Decimals(ref float fVal) { decimal decVal = Math.Round((decimal)fVal, 2); fVal = (float)decVal; double dVal = (double)fVal; }
Any other idea?You are still using float, aren't you ? :) what about this: double dVal = Math.Round((double)fVal, 2); if you need that value exactly, just use decimal in any calculation you are planing. If you want to display exactly 10.11, use decimal. If you're just wondering why is it different, we explained you why and don't worry about it anymore :)
zilo
-
ArtiGujare wrote:
Can any one help me understand what is happening?
-
You are still using float, aren't you ? :) what about this: double dVal = Math.Round((double)fVal, 2); if you need that value exactly, just use decimal in any calculation you are planing. If you want to display exactly 10.11, use decimal. If you're just wondering why is it different, we explained you why and don't worry about it anymore :)
zilo
The problem is that the third party dll uses float value in its class. So I really cant get rid of the float :-) and I still need to use this dll. As a work around I am using Math.Abs() method to find out tolerable difference between the two float values instead of checking exact difference using "==" with floats.
-
hello, math.round donot support float, its argument must be Double. for example : Double dblValue = 123.126789; dblValue = Math.Round(dblValue, 2); MessageBox.Show(dblValue.ToString());// Displays 123.13 I think u can continue your work. Best of Luck. :-O
Dipak
Sorry, you're mistaken. Your example happens to produce the result you want, but it is not correct. Here is the background: The way floats/doubles are stored in binary makes it impossible to exactly represent most values, especially the ones that seem like round numbers to humans thinking using base ten. So 4, 2, 1, 0.5, 3.5, 3.75 and many others are representable exactly (basically since they all equal an integer divided by some power of 2); but 3.6 and 3.8 and an infinite number of other values are not. Now whatever float/double function you call, if it returns a float/double will suffer from the same phenomenon. So the only way to really get "3.6" or "3.8" is by using a function that not only rounds but returns a string. I trust there are some formatting methods that do just that in every programming language; In .NET languages ToString() should be one of them, given an appropriate format specifier. If you want to know much more about this topic, here it is: http://docs.sun.com/source/806-3568/ncg\_goldberg.html BTW: to circumvent the floating-point rounding problem, especially for monetary numbers, they introduced the "decimal" data type (which basically stores decimal digits). :)
Luc Pattyn [Forum Guidelines] [My Articles]
Sorry for any delays in replying, I currently don't always get e-mail notifications.