为什么Excel VBA中的四舍五入函数会根据小数位数给出不同的结果?

为什么Excel VBA中的四舍五入函数会根据小数位数给出不同的结果?,excel,vba,rounding,bankers-rounding,Excel,Vba,Rounding,Bankers Rounding,我试图在电子表格中使用VBA Round函数,使用我在本论坛其他地方找到的这段方便的代码: Function BankerRound(rng As Double, sig As Integer) As Double BankerRound = Round(rng, sig) End Function 但我很惊讶这些结果都使用了2位小数 1233.71537501667 rounds to 1233.72 1233.715 rounds to 1233.71 有人能解释为什么结果不同吗

我试图在电子表格中使用VBA Round函数,使用我在本论坛其他地方找到的这段方便的代码:

Function BankerRound(rng As Double, sig As Integer) As Double
    BankerRound = Round(rng, sig)
End Function
但我很惊讶这些结果都使用了2位小数

1233.71537501667 rounds to 1233.72
1233.715 rounds to 1233.71

有人能解释为什么结果不同吗?

舍入算法在处理中间情况时有所不同。有关更多信息,请参阅维基百科讨论

关于所谓的银行家四舍五入,我认为银行家们不会使用这种方法,算法要求四舍五入到最近的偶数

因此,您的1233.715的特定示例应舍入到1233.72,与123.715舍入到123.72的方式大致相同

我认为,之所以没有这样做,可能是因为MS VBA处理十进制值的方式无法完全按照IEEE规范表示。最有可能的是,内部存储的值的十进制表示形式类似于1233.71499999

如果这很重要,您应该能够通过使用十进制数据类型获得所需的值,该数据类型存储为整数而不是浮点二进制

例如:

Function bankerRound(num As Variant, numDecimals As Long)
    bankerRound = Round(CDec(num), numDecimals)
End Function
为了进一步澄清?混乱?检查以下结果:

vbaRound函数使用双精度数据类型


舍入算法在处理中间情况时有所不同。有关更多信息,请参阅维基百科讨论

关于所谓的银行家四舍五入,我认为银行家们不会使用这种方法,算法要求四舍五入到最近的偶数

因此,您的1233.715的特定示例应舍入到1233.72,与123.715舍入到123.72的方式大致相同

我认为,之所以没有这样做,可能是因为MS VBA处理十进制值的方式无法完全按照IEEE规范表示。最有可能的是,内部存储的值的十进制表示形式类似于1233.71499999

如果这很重要,您应该能够通过使用十进制数据类型获得所需的值,该数据类型存储为整数而不是浮点二进制

例如:

Function bankerRound(num As Variant, numDecimals As Long)
    bankerRound = Round(CDec(num), numDecimals)
End Function
为了进一步澄清?混乱?检查以下结果:

vbaRound函数使用双精度数据类型


这就是round函数的工作方式。直到小数点后五位(含小数点后五位),向下取整,向上取整。你希望它如何工作?这两种情况之间的界限在哪里?@FaneDuru的银行家们四舍五入到一半时,应该总是四舍五入到偶数。你可能希望看到其中的链接。和@斯科特·克兰纳:Ups。。。我现在才看到Round1233.715,2返回对WorksheetFunction.Round1233.715,2的deferent。因此,函数必须根据他的意愿进行更改…@ScottCraner那么1233.715不应该转到1233.72吗?我想可能1233.715在内部存储为1233.71499999。毕竟,123.715轮到123.72轮这是轮函数的工作方式。直到小数点后五位(含小数点后五位),向下取整,向上取整。你希望它如何工作?这两种情况之间的界限在哪里?@FaneDuru的银行家们四舍五入到一半时,应该总是四舍五入到偶数。你可能希望看到其中的链接。和@斯科特·克兰纳:Ups。。。我现在才看到Round1233.715,2返回对WorksheetFunction.Round1233.715,2的deferent。因此,函数必须根据他的意愿进行更改…@ScottCraner那么1233.715不应该转到1233.72吗?我想可能1233.715在内部存储为1233.71499999。毕竟,123.715轮到123.72轮这是非常有帮助的,但我发现我在其他数字上仍然遇到同样的问题。例如,将函数7.68510四舍五入修改为7.69,将函数7.6850四舍五入修改为7.68。@OutThere:但是,函数似乎遵守将二分之一舍入为偶数的规则,因此,它仅在精确的0.5小数点的情况下才这样做。对于.51,这不是一半,它将被四舍五入。你对银行家四舍五入还有别的定义吗?我必须承认,我只是在现在才听说这种舍入方式,我试图理解它的含义以及为什么它会有用。关于这个意思,我在上面发表了一个观点。关于为什么它可能有用,我认为,与只在一个方向上进行舍入相比,它更好地平衡了发生的舍入错误。向上或向下…@外面,嗯。我想你误解了这个过程。舍入将给定的数字替换为最接近它的值,给定一些约束条件,例如小数位数。只有当给定的数字与两个约束等距时,不同的方案才会根据应做的事情而有所不同。在您将7.68510四舍五入为两位小数的示例中,显然7.68510更接近于7.69,而不是7.68。所以四舍五入到7.69是合适的。但是,7.685与7.68和7.69的距离相等,将根据所使用的方案进行四舍五入。@FaneDuru。有一个有趣的讨论
不同的舍入方法,以及它们的优点和缺点,有什么区别?我看不出任何地方有这样的定义。这很有帮助,但我发现我对其他数字仍然有同样的问题。例如,将函数7.68510四舍五入修改为7.69,将函数7.6850四舍五入修改为7.68。@OutThere:但是,函数似乎遵守将二分之一舍入为偶数的规则,因此,它仅在精确的0.5小数点的情况下才这样做。对于.51,这不是一半,它将被四舍五入。你对银行家四舍五入还有别的定义吗?我必须承认,我只是在现在才听说这种舍入方式,我试图理解它的含义以及为什么它会有用。关于这个意思,我在上面发表了一个观点。关于为什么它可能有用,我认为,与只在一个方向上进行舍入相比,它更好地平衡了发生的舍入错误。向上或向下…@外面,嗯。我想你误解了这个过程。舍入将给定的数字替换为最接近它的值,给定一些约束条件,例如小数位数。只有当给定的数字与两个约束等距时,不同的方案才会根据应做的事情而有所不同。在您将7.68510四舍五入为两位小数的示例中,显然7.68510更接近于7.69,而不是7.68。所以四舍五入到7.69是合适的。但是,7.685与7.68和7.69的距离相等,将根据所使用的方案进行四舍五入。@FaneDuru。有一个有趣的关于不同舍入方法的讨论,以及它们的优缺点,关于VBA是什么?我看不出有什么定义。