四舍五入VS银行家舍入

系统 1435 0

相信细心的程序员们早就发现了 .net 环境下默认舍入算法的是“四舍六入”的算法。从小学我们就学过“四舍五入”算法,但是更加科学的舍入办法应该是“四舍六入”,也就是今天我们要讨论的“ 银行家舍入 ”。

大家可以做一个 Demo

C# 环境下

        
             1:  
        
        
          class
        
         Program
      
        
             2:  
        
            {
      
        
             3:  
        
        
          static
        
        
          void
        
         Main(
        
          string
        
        [] args)
      
        
             4:  
        
                { 
      
        
             5:  
        
        
          do
        
      
        
             6:  
        
                   {
      
        
             7:  
        
                        Console.WriteLine(
        
          "请输入一个小数回车测试,输入其他回车结束测试"
        
        );
      
        
             8:  
        
        
          string
        
         Num = Console.ReadLine();
      
        
             9:  
        
        
          try
        
      
        
            10:  
        
                        {
      
        
            11:  
        
                            Console.WriteLine(
        
          "结果为"
        
         + Convert.ToInt16(Convert.ToDouble(Num)));
      
        
            12:  
        
                        }
      
        
            13:  
        
        
          catch
        
         (Exception e) {
      
        
            14:  
        
        
          break
        
        ;
      
        
            15:  
        
                        } 
      
        
            16:  
        
                   }
      
        
            17:  
        
        
          while
        
         (
        
          true
        
         );
      
        
            18:  
        
                }
      
        
            19:  
        
            }
      

得到的结果如下

<style type="text/css"> <!-- .csharpcode, .csharpcode pre {font-size:small; color:black; font-family:consolas,"Courier New",courier,monospace; background-color:#ffffff} .csharpcode pre {margin:0em} .csharpcode .rem {color:#008000} .csharpcode .kwrd {color:#0000ff} .csharpcode .str {color:#006080} .csharpcode .op {color:#0000c0} .csharpcode .preproc {color:#cc6633} .csharpcode .asp {background-color:#ffff00} .csharpcode .html {color:#800000} .csharpcode .attr {color:#ff0000} .csharpcode .alt {background-color:#f4f4f4; width:100%; margin:0em} .csharpcode .lnum {color:#606060} --> </style>

image

VB.net 环境下测试代码为

        
             1:  
        
            Sub Main()
      
        
             2:  
        
                Do
      
        
             3:  
        
                    Console.WriteLine(
        
          "请输入一个小数回车测试,输入其他回车结束测试。"
        
        )
      
        
             4:  
        
                    Try
      
        
             5:  
        
                        Dim a As String = Console.ReadLine()
      
        
             6:  
        
                        Console.WriteLine(
        
          "结果为:"
        
         & CInt(Convert.ToDouble(a)))
      
        
             7:  
        
                    Catch ex As Exception
      
        
             8:  
        
                        Exit Sub
      
        
             9:  
        
                    End Try
      
        
            10:  
        
                Loop
      
        
            11:  
        
            End Sub
      

结果如下

image

完全符合银行家舍入的规律:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一

关于 VB.net 中的 CInt 微软的 MSDN 上有具体说明

Fractional Parts. When you convert a nonintegral value to an integral type, the integer conversion functions ( CByte , CInt , CLng , CSByte , CShort , CUInt , CULng , and CUShort ) remove the fractional part and round the value to the closest integer.

If the fractional part is exactly 0.5, the integer conversion functions round it to the nearest even integer. For example, 0.5 rounds to 0, and 1.5 and 2.5 both round to 2. This is sometimes called banker's rounding , and its purpose is to compensate for a bias that could accumulate when adding many such numbers together.

相对于四舍五入,银行家舍入的确更加的准确,讨论如下:

有些童鞋可能认为在一般性的测量中,最后一位小数位上 0 9 出现的概率是相等的。一共十个数字, 0 4 可以舍去(四舍), 5 9 可以进位(五入),多么完美的舍入算法!

但是!您可能忽略了一点,末尾的 0 在这里是相当于 10 还是相当于 0

为了避免混沌,请看下图:

<style type="text/css"> <!-- .csharpcode, .csharpcode pre {font-size:small; color:black; font-family:consolas,"Courier New",courier,monospace; background-color:#ffffff} .csharpcode pre {margin:0em} .csharpcode .rem {color:#008000} .csharpcode .kwrd {color:#0000ff} .csharpcode .str {color:#006080} .csharpcode .op {color:#0000c0} .csharpcode .preproc {color:#cc6633} .csharpcode .asp {background-color:#ffff00} .csharpcode .html {color:#800000} .csharpcode .attr {color:#ff0000} .csharpcode .alt {background-color:#f4f4f4; width:100%; margin:0em} .csharpcode .lnum {color:#606060} --> </style>

image

图中是用 Matlab 画的一个简单的数轴,可以看出 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.0 1.0 都是 0 结尾所以不能确定测量数据中的 0 是哪个零!

还是看上图,图中只要不满 0.5 都按照 0 算,大于 0.5 都按照 1.0 算,那么剩下的 0.5 怎么办?为了体现平均性,看上一位是奇数还是偶数,如果是奇数则进位,如果是偶数则舍去。这正是“银行家舍入”的思想。这样一来便达到了相对于“四舍五入”舍入方法更加平衡的舍入算法。

PS :“银行家舍入”是 IEEE 规定的舍入标准。因此所有符合 IEEE 标准 的语言都是采用这一算法的。

四舍五入VS银行家舍入


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论