It's also called "Banker's Rounding". VB does this as well.

-----Original Message-----
From: Mark Hills [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, August 28, 2002 7:13 AM
To: [EMAIL PROTECTED]
Subject: Re: [ADVANCED-DOTNET] Math.Log odd rounding behavior


Just as an aside (and maybe not a very interesting one), rounding toward
the even number is actually considered standard, at least for computers,
even if it isn't what anyone thinks of when they think of rounding. When
I took a numerical analysis course in college we were taught to do this
since it minimized errors introduced through rounding. The thought is
that, if you always round up at .5, you will introduce more error than
if you round toward the even number, since you then have a better chance
of the rounding operations evening each other out over time.

If you look on Google for IEEE rounding, I think there's some documents
out there on this. You will see the round toward even referred to as
something like standard rounding or rounding toward the nearest
representative value, while rounding up will probably be referred to as
rounding toward positive infinity.

Mark


> -----Original Message-----
> From: Moderated discussion of advanced .NET topics.
> [mailto:[EMAIL PROTECTED]] On Behalf Of
> Christoph Nahr
> Sent: Tuesday, August 27, 2002 8:31 AM
> To: [EMAIL PROTECTED]
> Subject: Re: [ADVANCED-DOTNET] Math.Log odd rounding behavior
>
>
> John,
>
> Are you familiar with the inherent inexactness of
> floating-point (FP) operations?  If not then I would
> recommend that you first read Bruce M. Bush's highly
> informative paper "The Perils of Floating Point" at the Lahey
> website: http://www.lahey.com/float.htm
>
> Briefly, FP operations may not give the expected result (e.g.
> 3.0) but some other result in the vicinity (e.g. 2.999...),
> and that's probably what happened in your case.  The output
> functions of WriteLine and the debugger were apparently
> clever enough to provide enough rounding so that a seemingly
> exact value was output, but the int cast simply cut off the
> .9999 sequence and gave 2.0 as the result.
>
> To see the actual representation of an FP value, instead of
> the rounded one produced by most print functions, use the
> "round-trip" format specifier likes this:
> Console.WriteLine("Log2(8) = {0:r}", Math.Log(8,2));
>
> This command prints 2.9999999999999996 (15 times 9) which an
> int cast would correctly round to 2.  This is with .NET SP2,
> by the way.
>
> That said, there does seem to be a .NET-specific problem
> here.  A similar test program written in C and compiled into
> native code by MS VC++ .NET gives 3.0 as the result of
> log(8.0)/log(2.0).  There are only zeroes after the decimal
> point as far as the eye can see (I tried 30 digits; the
> double type is only guaranteed to have 15 digits of
> precision), and casting to int also yields 3 and not 2.
>
> So either the Math.Log algorithm is less exact than the log
> function of the C library, or the C compiler is clever enough
> to do some slight rounding of its own as required -- after
> all, the 6 in the .NET result above came after 16 other
> digits and hence was past the guaranteed precision of the
> System.Double type (same as double: 15 digits).  Microsoft
> definitely should look into this.
>
> In the meantime, you should either use Math.Round before
> casting to int, or use Convert.ToInt32 which rounds & casts
> in one step.  However, both methods will apply the bizarre
> "banker's rounding", i.e. rounding to even, which Microsoft
> inflicted upon us for unknown reasons.  If you want real
> rounding you have to write it yourself:
>
> double d = Math.Log(8, 2);
> int i = (int) (d > 0.0 ? d + 0.5 : d - 0.5);
>
> The second line will round any FP value d to the nearest int.
>  The comparison to zero is required in the general case,
> though not in this example.
>
> Cheers, Christoph
>
> At 10:31 25.08.2002 -0700, you wrote:
> >Given the following simple program:
> >using System;
> >public class RoundingError {
> >   public static void Main(string[] args) {
> >     Console.WriteLine("Log2(8) = {0}", (int) Math.Log(8,2));
> >   }
> >}
> >
> >The output is 2 if you run it standalone, but 3 (the
> expected value) if
> >run from within the Visual Studio.NET debugger. If you print
> the double
> >version of the return value, it is 3 in both cases...
> >
> >Any ideas what could be going on? I have not tried applying SP1.
> >
> >Thanks,
> >John
> >
> >You can read messages from the Advanced DOTNET archive, unsubscribe
> >from Advanced DOTNET, or subscribe to other DevelopMentor lists at
> >http://discuss.develop.com.
>
> You can read messages from the Advanced DOTNET archive,
> unsubscribe from Advanced DOTNET, or subscribe to other
> DevelopMentor lists at http://discuss.develop.com.
>

You can read messages from the Advanced DOTNET archive, unsubscribe from
Advanced DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to