zoukankan      html  css  js  c++  java
  • C# Round源码

    在日常开发中经常遇到四舍五入的情况比如 Math.Round(1.25, 1),首先我们要知道这里的Round 其实是银行家算法,具体可以参考Round() 四舍五入 js银行家算法 那么C#是如何实现的了,我们来看看decimal的round实现如下:

      
           [System.Security.SecuritySafeCritical]  // auto-generated
            public static Decimal Round(Decimal d, int decimals)
            {
                FCallRound (ref d, decimals);
                return d;
            }
    
            public static Decimal Round(Decimal d, MidpointRounding mode) {
                return Round(d, 0, mode);
            }
      
      
            [System.Security.SecuritySafeCritical]  // auto-generated
            public static Decimal Round(Decimal d, int decimals, MidpointRounding mode) {
                if ((decimals < 0) || (decimals > 28))
                    throw new ArgumentOutOfRangeException("decimals", Environment.GetResourceString("ArgumentOutOfRange_DecimalRound"));
                if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) {            
                    throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, "MidpointRounding"), "mode");
                }
                Contract.EndContractBlock();
    
                if (mode == MidpointRounding.ToEven) {
                    FCallRound (ref d, decimals);
                }
                else {
                    InternalRoundFromZero(ref d, decimals);
                }
                return d;
            }
    
            [System.Security.SecurityCritical]  // auto-generated
            [ResourceExposure(ResourceScope.None)]
            [MethodImplAttribute(MethodImplOptions.InternalCall)]
            private static extern void FCallRound(ref Decimal d, int decimals);
            
    
      // Does an in-place round the specified number of digits, rounding mid-point values
            // away from zero
            private static void InternalRoundFromZero(ref Decimal d, int decimalCount) {
                Int32 scale = (d.flags & ScaleMask) >> ScaleShift;
                Int32 scaleDifference = scale - decimalCount;
                if (scaleDifference <= 0) {
                    return;
                }
                // Divide the value by 10^scaleDifference
                UInt32 lastRemainder;
                UInt32 lastDivisor;
                do {
                    Int32 diffChunk = (scaleDifference > MaxInt32Scale) ? MaxInt32Scale : scaleDifference;
                    lastDivisor = Powers10[diffChunk];
                    lastRemainder = InternalDivRemUInt32(ref d, lastDivisor);
                    scaleDifference -= diffChunk;
                } while (scaleDifference > 0);
                
                // Round away from zero at the mid point
                if (lastRemainder >= (lastDivisor >> 1)) {
                    InternalAddUInt32RawUnchecked(ref d, 1);
                }
                
                // the scale becomes the desired decimal count
                d.flags = ((decimalCount << ScaleShift) & ScaleMask) | (d.flags & SignMask);
            }

    所以我们如果想要四舍五入 那么方法必须穿入MidpointRounding 参数,调用托管代码;不传这是银行家算法调用非托管代码,从性能的角度讲应该竟可能调用托管代码。所以除非有要求,尽力调用托管代码吧。

  • 相关阅读:
    Go语言使用grpc
    Go语言中使用protobuf
    proto3语法
    golang标准库io
    走近docker--容器生态系统
    编译技术图式(第四章 语义分析)
    计算机组成原理与结构图示(存储器设计)
    微机原理与汇编接口图式(第一章 数制)
    编译技术图式(第四章 语法分析)03自下而上的语法分析
    计算机组成原理和结构图式(第四章 存储器子系统)
  • 原文地址:https://www.cnblogs.com/majiang/p/7058945.html
Copyright © 2011-2022 走看看