0

Over the last 2 days I have been doing a LOT of reading about decimal vs. double about rounding.

What I would like to know is does anyone know how the Math.Round actually works under the covers? Like does it do a conversion to bits then do rounding on those bits or does it round first etc? Does it import or execute any native code that does the rounding ? etc

If anyone has any technical whitepapers or links, that would be awesome!

rene
  • 41,474
  • 78
  • 114
  • 152
h4ck3r8ug5
  • 87
  • 8
  • Read the [source code](http://www.dotnetframework.org/default.aspx/Net/Net/3@5@50727@3053/DEVDIV/depot/DevDiv/releases/whidbey/netfxsp/ndp/clr/src/BCL/System/Math@cs/1/Math@cs). – Kirk Woll Nov 01 '13 at 05:59
  • If you get IL Spy, decompile the DLL and have a look for yourself. – David Pilkington Nov 01 '13 at 06:00

1 Answers1

1

Taken from mscorlib.dll using a decompiler. Note there are a number of other calls that are important. I suggest getting a decompiler and stepping through it yourself. Cheers

[__DynamicallyInvokable]
[SecuritySafeCritical]
public static extern double Round(double a);

[__DynamicallyInvokable]
public static double Round(double value, int digits)
{
    if (digits < 0 || digits > 15)
    {
        throw new ArgumentOutOfRangeException("digits", Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
    }
    return Math.InternalRound(value, digits, MidpointRounding.ToEven);
}


[SecuritySafeCritical]
private static double InternalRound(double value, int digits, MidpointRounding mode)
{
    unsafe
    {
        if (Math.Abs(value) < Math.doubleRoundLimit)
        {
            double num = Math.roundPower10Double[digits];
            value = value * num;
            if (mode != MidpointRounding.AwayFromZero)
            {
                value = Math.Round(value);
            }
            else
            {
                double num1 = Math.SplitFractionDouble(ref value);
                if (Math.Abs(num1) >= 0.5)
                {
                    value = value + (double)Math.Sign(num1);
                }
            }
            value = value / num;
        }
        return value;
    }
}
Nico
  • 12,493
  • 5
  • 42
  • 62
  • 1
    I have just decompiled Math.Round using JustDecompile and I have noticed that theres an initial Round method declaration marked as extern. To my knowledge, this means that the method is implemented externally, do u know which library that Round method comes from? – h4ck3r8ug5 Nov 01 '13 at 06:21
  • Have a look here http://stackoverflow.com/questions/8870442/how-is-math-pow-implemented-in-net-framework although it is talking about POW also is applicable to Round. – Nico Nov 01 '13 at 06:26