Excel VBA如何将Double数据类型四舍五入为整数?

4
我将尝试理解在VBA中声明错误类型变量时可能发生的错误类型。以下是我正在使用的代码:
Sub testTypes()

Dim test1 As Integer
test1 = 0.5

Debug.Print test1

End Sub

我有意使用Double数值类型,以查看VBA如何将它们(向上或向下)四舍五入为整数,因为数字以.5结尾。

结果让我感到困惑:

5.567 --> 6
5.5 --> 6
4.5 --> 4
3.5 --> 4
2.5 --> 2
1.5 --> 2
0.5 --> 0

有人能解释一下Excel如何确定是向上还是向下取整吗?


5
它会向最接近的偶数舍入,这被称为“银行家舍入”。 - Scott Craner
1
@Scott 从未知道,谢谢你的提示!@Sandra 如果你想强制四舍五入或向下取整,可以使用 WorksheetFunction.RoundUp(test1, 0)(或者使用相同语法的 RoundDown)。 - barvobot
嘿@ScottCraner,感谢您指出这个问题!我认为我找到的这个定义更加清晰: “如果5前面的数字是奇数,则向上取整。如果是偶数,则向下取整。”例子 1.1235 四舍五入为 1.124 1.1225 四舍五入为 1.122 - Sandra
这里用到了 IEEE 754。请查看 Ostemar 在 为什么.NET默认使用银行家舍入? 中的回答,以核实答案。还可以参考 2003 年发布的 MS文章!想象一下,在没有这个标准的情况下,十亿个这样的舍入误差的总和可能对实际总和产生影响! - PatricK
2个回答

1
为了避免所谓的银行家舍入(=中间值5总是舍入到最接近的偶数),您可以使用以下方法之一:
  • (1) WorkSheetFunction.Round
  • (2) 用户定义函数。
银行家舍入是在金融和统计操作中使用的标准舍入形式,以通过始终将中间值舍入到单个方向来最小化多次舍入操作中的重大舍入误差。 (1) 使用WorksheetFunction Round()的示例:
Sub RoundWithWorkSheetFunction()
' Purpose: avoid so called bankers' rounding in VBA (5 always rounds even)
With WorksheetFunction
    Debug.Print "WorksheetFunction.Round(3.5, 0)=" & .Round(3.5, 0), ":| VBA rounds to " & Round(3.5, 0)
    Debug.Print "WorksheetFunction.Round(4.5, 0)=" & .Round(4.5, 0), ":| VBA rounds to " & Round(4.5, 0)
End With

End Sub

(2) 避免银行家舍入的工作表函数替代方案:

Function roundIt(ByVal d As Double, ByVal nDigits As Integer) As Double
' Purpose: avoid so called bankers' rounding in VBA (5 always rounds even)
If nDigits > 0 Then
   ' if continental european colon instead of point separartor
   ' roundIt= val(Replace(Format(d, "0." & String(nDigits, "0")), ",", "."))
     roundIt = Val(Format(d, "0." & String(nDigits, "0")))
Else
   ' if continental european colon instead of point separartor
   ' roundIt =  val(Replace(Format(d / (10 ^ nDigits), "0."), ",", "."))
   roundIt = Val(Format(d / (10 ^ nDigits), "0."))
End If
End Function

0
Sandra,它会根据数字是偶数还是奇数来四舍五入。如果是偶数,它将向下取整。否则,它将向上取整。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接