软件注册站
热情软件屋

 
VB的ROUND四舍五入函数是否有BUG
编号: QA002253    
建立日期: 1999年12月14日 最后修改日期: 2004年2月29日
所属类别: Visual Basic - 其他方面
   
    操作系统: pwin98
    编程工具: vb6.0 sp3
    问题: 请问VB的ROUND四舍五入函数是否有BUG?在VB的立即窗口中输入以下命令:
    AA=123.125
    ?ROUND(AA,2) '返回2位小数
    VB返回为123.12
    而将AA赋值为123.126
    VB返回为123.13
    这是明显错误的,为什么?(fjf)
   
    李海、majun、lym等的意见:
    VB6中文版说这个函数是四舍五入函数,实际上这个函数采用的四舍六入五留双。VB的Round所采用的算法是这样的:
    1.25留一位,则1.2=round(1.25)
    如果是1.35,则1.4=round(1.35)
    奇进偶不进。这样在一大串需要四舍五入的数相加相减相乘时误差小一点。eg:1.25+1.35+1.45+1.55+1.15+1.65=8.4=round(1.25)+round(1.35)+round(……
    ROUND函数符合国家和国际标准,该函数是正确的。原先的四舍五入只是一个简化。
    在微软的Knowledge Base的文章:“Q194983 PRB: Round Function Different in VBA 6 and Excel Spreadsheet”和微软的Knowledge Base的文章:“Q189847 INFO: New String and Format Functions in Visual Basic 6.0”中都指出Round函数实行Banker舍入,而不是我们习惯的算术舍入(四舍五入)。你可以参考微软的Knowledge Base的文章:“Q196652 HOWTO: Implement Custom Rounding Procedures”,它对于舍入问题有详细的讨论。
    
    sapphire的意见:
    最好的方法INT(I+0.5)。INT函数是相当于舍弃小数位的函数,将浮点数在数轴上向左找最近的整数,FIX函数是向0点找最近的整数,综上所述,使用INT函数将原有的数字进行+0.5然后取整,在C中强制类型转换取整实现四舍五入是同样的原理。
    
    zcw的意见:
    Function RoundEx(Number, Optional nLen As Long = 0)
    On Error GoTo ErrRound
     Dim dblAdd As Double
    
     dblAdd = 10 ^ (-nLen - 1)
     If Number < 0 Then dblAdd = -dblAdd
     Number = Number + dblAdd
     RoundEx = Round(Number, nLen)
    
     Exit Function
    ErrRound:
     MsgBox "实时错误:" & Err.Number & vbCrLf & vbCrLf & Err.Description, vbExclamation, "错误提示"
    End Function
    

    
    王志坚、ALEX的意见:
    对此问题可自定义函数解决。
    Function Round (X as Double, DP as integer) as Double
     X = X*10 ^ DP + 0.5
     Round = Int( X ) / 10 ^ DP
    End Function
    
    

    
    刘庆的意见:
    其实最简单的办法VB已经提供了,FORMAT(123456.789,"###,###.##")函数,这可是真的四舍五入,而不是四舍六入五留双啊!发现在WINXP中FORMAT函数达不到预期的效果了,装了SP也不见效,不得不试了以上各位的方法,可总有数据类型转换的问题不太完善,便做了下面这个函数,望各位斧正。
    Public Function Round45(n As Double, p As Integer) As Double
     Dim s As String, a As String, b As String, x As String, v As Double
    
     If n = 0 Or p < 0 Then Round45 = "": Exit Function
     s = Trim(Str(n))
     If InStr(s, ".") <> 0 Then
     a = Mid(s, 1, InStr(s, ".") - 1)
     b = Mid(s, InStr(s, ".") + 1)
     Else
     a = s
     b = ""
     End If
     If Len(b) <= p Then
     Round45 = CDbl(Val(a + "." + b))
     Exit Function
     Else
     If Val(Mid(b, p + 1, 1)) >= 5 Then
     x = a + Mid(b, 1, p)
     v = CDbl(Val(x))
     v = v + 1#
     v = v / (10 ^ p)
     Round45 = v
     Exit Function
     Else
     Round45 = CDbl(Val(a + "." + b))
     Exit Function
     End If
     End If
    End Function
    

    
    夏鲲鹏的意见:
    '对称型舍入(四舍五入)
    Public Function Round(ByVal dblNumber As Double, Optional ByVal intFactor As Integer = 0) As Double
    Round = Fix(cdbl(dblNumber * 10 ^ intFactor + 0.5 * Sgn(dblNumber))) / 10 ^ intFactor
    End Function
    
    

    注意:在XP系统下有以下BUG:
    fix(12.565*100+0.5)=1256
    fix(cdbl(12.565*100+0.5))=1257
    所以必须使用CDbl转换。

    

此问题由李海等回答。

附加关键字:编程, 源程序, programming, source code, Visual Basic, VB, 其他方面,

   
 
把这个问题推荐给朋友
   
 
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio