468,720 Members | 1,732 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,720 developers. It's quick & easy.

Math.Round problem

I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in certain
situations in my code.

The workaround I have implemented is of the form Math.Round(val + 1e-12,
places); however it's pretty ugly.

Help would be appreciated, thanks,

David.
Sep 20 '06 #1
10 15439
David Coleman wrote:
I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in certain
situations in my code.

The workaround I have implemented is of the form Math.Round(val + 1e-12,
places); however it's pretty ugly.
That is a classic floating point problem.

If it is a problem for you, then floating point is
probably not the correct data type.

Maybe you should use decimal ??

BTW, your workaround can create other problems if you numbers
can take full range.

Arne
Sep 20 '06 #2
David Coleman wrote:
I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in certain
situations in my code.

The workaround I have implemented is of the form Math.Round(val + 1e-12,
places); however it's pretty ugly.

Help would be appreciated, thanks,

David.

I think you want the MidpointRounding.AwayFromZero enum value.
If you always want to round 5 "up" (down if less than zero) then this is
what you want.

By default it appears to use MidpointRounding.ToEven which will round
towards the nearest even number.
Ie .115 will be rounded to .12, .125 will also be rounded to .12.
HTH

JB
Sep 20 '06 #3
John B wrote:
David Coleman wrote:
>I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in
certain situations in my code.

The workaround I have implemented is of the form Math.Round(val +
1e-12, places); however it's pretty ugly.

Help would be appreciated, thanks,

David.
I think you want the MidpointRounding.AwayFromZero enum value.
If you always want to round 5 "up" (down if less than zero) then this is
what you want.

By default it appears to use MidpointRounding.ToEven which will round
towards the nearest even number.
Ie .115 will be rounded to .12, .125 will also be rounded to .12.
oops, Math.Round(value, decimalplaces, MidpointRounding.AwayFromZero) :)
>
HTH

JB
Sep 20 '06 #4
Thanks John B,

Explains the problem. But with VS 2003 Math.Round doesn't have a
MidpointRounding parameter overload.

All my business type calculations are done in static methods in calculations
classes so it's no big deal to do the fudge code for now.

Cheers,

David.

"John B" <jb******@yahoo.comwrote in message
news:45**********@news.iprimus.com.au...
John B wrote:
>David Coleman wrote:
>>I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in
certain situations in my code.

The workaround I have implemented is of the form Math.Round(val + 1e-12,
places); however it's pretty ugly.

Help would be appreciated, thanks,

David.
I think you want the MidpointRounding.AwayFromZero enum value.
If you always want to round 5 "up" (down if less than zero) then this is
what you want.

By default it appears to use MidpointRounding.ToEven which will round
towards the nearest even number.
Ie .115 will be rounded to .12, .125 will also be rounded to .12.

oops, Math.Round(value, decimalplaces, MidpointRounding.AwayFromZero) :)
>>
HTH

JB

Sep 20 '06 #5
David Coleman wrote:
Thanks John B,

Explains the problem. But with VS 2003 Math.Round doesn't have a
MidpointRounding parameter overload.

All my business type calculations are done in static methods in calculations
classes so it's no big deal to do the fudge code for now.
Hmm, didnt know that about 1.1.
A "hack" suggested in a previous post
http://groups.google.com.au/group/mi...4df858f6200f1e
is to call ToString("#.##") which does 5/4 rounding.
<...>

:(

JB
Sep 20 '06 #6
David Coleman <co******@hotmail.comwrote:
I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.
Which is exactly what the documentation says it will do.

<quote>
Return Value
The number nearest value with a precision equal to digits. If value is
halfway between two numbers, one of which is even and the other odd,
then the even number is returned. If the precision of value is less
than digits, then value is returned unchanged.
</quote>

If you're using .NET 2.0 and want a different sort of rounding, specify
a MidpointRounding to use.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Sep 20 '06 #7
Another workaround:

Math.Ceiling((0.725 * 100)+.5)/100

----- Original Message -----
From: "David Coleman" <co******@hotmail.com>
Newsgroups: microsoft.public.dotnet.languages.csharp
Sent: Wednesday, September 20, 2006 5:25 AM
Subject: Math.Round problem

>I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in
certain situations in my code.

The workaround I have implemented is of the form Math.Round(val + 1e-12,
places); however it's pretty ugly.

Help would be appreciated, thanks,

David.

Sep 20 '06 #8
PS
"David Coleman" <co******@hotmail.comwrote in message
news:ef**************@TK2MSFTNGP04.phx.gbl...
>I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in
certain situations in my code.

The workaround I have implemented is of the form Math.Round(val + 1e-12,
places); however it's pretty ugly.
This is known as banker's rounding. When working with rounding, always
rounding 0.5 up is not really fair. When dealing with money there would be a
bias. Compare the totals of your examples using the original numbers and the
rounded numbers. On the original total of 2.175 you want the total of the
rounded numbers to be 2.19 but using the examples you provided the total is
2.18.

If you have used the same rounding rules everywhere you should not have
rounding differences. However, you can't expect the total of rounded numbers
to equal the rounded total though. You will almost certainly have rounding
errors which is why you probably have a 1 cent difference. You need to
decide on a) what type of rounding you want and b) will you keep the rounded
figure or the original figure. If you keep the original figure then be
prepared for rounding errors like 0.03 + 0.03 + 0.03 = 0.10 (because 0.03
was really 0.034).

HTH

PS

Sep 20 '06 #9
I hope you mean Math.Floor (consider 0.726)

/claes

"Christof Nordiek" <cn@nospam.dewrote in message
news:uo**************@TK2MSFTNGP04.phx.gbl...
Another workaround:

Math.Ceiling((0.725 * 100)+.5)/100

----- Original Message -----
From: "David Coleman" <co******@hotmail.com>
Newsgroups: microsoft.public.dotnet.languages.csharp
Sent: Wednesday, September 20, 2006 5:25 AM
Subject: Math.Round problem

>>I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in
certain situations in my code.

The workaround I have implemented is of the form Math.Round(val + 1e-12,
places); however it's pretty ugly.

Help would be appreciated, thanks,

David.


Sep 20 '06 #10
Arne Vajhj wrote:
David Coleman wrote:
>I am running VS 2003 and have applied SP1. (On WinXP SP2, .Net 1.1)

In the Command Window I get the following

? Math.Round(0.715, 2)
0.72
? Math.Round(0.725, 2)
0.72
? Math.Round(0.735, 2)
0.74

That is not a typo. ? Math.Round(0.725, 2) indeed returns 0.72.

This appears to be the reason I get a 1 cent rounding difference in
certain situations in my code.

The workaround I have implemented is of the form Math.Round(val +
1e-12, places); however it's pretty ugly.

That is a classic floating point problem.

If it is a problem for you, then floating point is
probably not the correct data type.

Maybe you should use decimal ??
As other has pointed out, then the reason for the numbers
above being rounded as they are is the bankers rounding
(I did know that Round did bankers rounding).

But my point is still valid. You can not expect results that
make sense from a decimal number system perspective
when you use floating point.

Console.WriteLine(Math.Round(1.015, 2));
Console.WriteLine(Math.Round(2.015, 2));
Console.WriteLine(Math.Round(3.015, 2));
Console.WriteLine(Math.Round(4.015, 2));
outputs:

1,01
2,02
3,02
4,01

The correct solution is to use decimal. And specify the rounding
you want (I suspect that Round decimal is also using bankers
rounding by default).

Arne
Sep 21 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Tom | last post: by
5 posts views Thread by Ark | last post: by
6 posts views Thread by ng_mr | last post: by
6 posts views Thread by Mitchell Vincent | last post: by
4 posts views Thread by Chris Davoli | last post: by
3 posts views Thread by Altman | last post: by
4 posts views Thread by =?Utf-8?B?UmVuZQ==?= | last post: by
1 post views Thread by CARIGAR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.