Reputation: 1630
I have encountered a weird case in Math.Round function in VB.Net
Math.Round((32.625), 2)
Result : 32.62
Math.Round((32.635), 2)
Result : 32.64
I need 32.63 but the function is working in different logic in these cases.
I can get the decimal part and make what I want doing something on it. But isn't this too weird, one is rounding to higher, one is rounding to lower.
So how can I get 32.63 from 32.625 without messing with decimal part ? (as the natural logic of Maths)
Upvotes: 19
Views: 61845
Reputation: 186
Hers a quick function you can add to simplify your life and make it so you don't have to type so much all the time.
Private Function roundd(dec As Decimal)
Dim d As Decimal = dec
Dim r As Decimal = Math.Ceiling(d * 100D) / 100D
Return r
End Function
Add this to your application then use the function
roundd(3.624)
or whatever you need.
to display the result - example
msgbox(roundd(3.625))
This will display a messagebox with 3.63
Textbox1.text = roundd(3.625)
this will set textbox1.text - 3.63 etc. etc. So if you need to round more then one number, it won't be so tedious and you can save alot of typing.
Hope this helps.
Upvotes: 2
Reputation: 186
Try this.
Dim d As Decimal = 3.625
Dim r As Decimal = Math.Ceiling(d * 100D) / 100D
MsgBox(r)
This should do what you want.
Upvotes: 2
Reputation: 43743
Math.Round
uses banker's rounding by default. You can change that by specifying a different MidPointRounding
option. From the MSDN:
Rounding away from zero
Midpoint values are rounded to the next number away from zero. For example, 3.75 rounds to 3.8, 3.85 rounds to 3.9, -3.75 rounds to -3.8, and -3.85 rounds to -3.9. This form of rounding is represented by the MidpointRounding.AwayFromZero enumeration member. Rounding away from zero is the most widely known form of rounding.
Rounding to nearest, or banker's rounding
Midpoint values are rounded to the nearest even number. For example, both 3.75 and 3.85 round to 3.8, and both -3.75 and -3.85 round to -3.8. This form of rounding is represented by the MidpointRounding.ToEven enumeration member.
Rounding to nearest is the standard form of rounding used in financial and statistical operations. It conforms to IEEE Standard 754, section 4. When used in multiple rounding operations, it reduces the rounding error that is caused by consistently rounding midpoint values in a single direction. In some cases, this rounding error can be significant.
So, what you want is:
Math.Round(32.625, 2, MidpointRounding.AwayFromZero)
Math.Round(32.635, 2, MidpointRounding.AwayFromZero)
As others have mentioned, if precision is important, you should be using Decimal
variables rather than floating point types. For instance:
Math.Round(32.625D, 2, MidpointRounding.AwayFromZero)
Math.Round(32.635D, 2, MidpointRounding.AwayFromZero)
Upvotes: 41
Reputation: 2655
Try this (from memory):
Math.Round((32.635), 2, MidPointRounding.AwayFromZero)
Upvotes: 4
Reputation: 32681
You can't using floats which is what numbers like 32.625 is treated as in VB.Net. (There is also the issue of Banker's rounding as mention by @StevenDoggart - you are probably going to have to deal with both issues.)
The issue is that the number stored is not exactly what is entered because these numbers do not into a fixed binary representation e.g. 32.625 is stored as 32.62499997 and 32.635 as 32.63500001.
The only way to be exact is to store the numbers as the type Decimal
DIM num as Decimal
num = ToDecimal("32.625")
Upvotes: -1