Excel VBA获取数字小数部分:Int()方法异常原因及最优方案咨询
Excel VBA 获取小数部分的问题解析与最优方案
为什么会出现奇怪的小数结果?
你遇到的9.99999999999996E-02不是代码bug,而是Double类型的浮点数精度限制导致的:
- Double是二进制浮点数,很多十进制小数(比如0.1)无法被二进制精确表示,存储的是一个极其接近的近似值。
- 你定义的
DecNumber = 15.1,实际在内存里存储的是接近15.1但略小于它的数值,所以用DecNumber - Int(DecNumber)计算时,得到的是这个近似值的小数部分,也就出现了看似异常的结果。
最优实现方案
方案1:用Decimal类型规避精度问题
先把Double转成Decimal类型(Decimal是十进制浮点数,能精确表示十进制小数),再计算小数部分:
Dim DecNumber As Double Dim DecFract As Double DecNumber = 15.1 DecFract = CDec(DecNumber) - Int(CDec(DecNumber)) ' 此时DecFract会精确得到0.1
方案2:对结果进行四舍五入
如果不需要绝对精确,只是要消除显示的微小误差,可以用Round函数指定小数位数:
DecFract = Round(DecNumber - Int(DecNumber), 1) ' 针对15.1这种1位小数的情况,指定保留1位小数即可得到0.1
方案3:字符串拆分(需处理边界情况)
你用的字符串拆分方法能得到正确结果,但要注意当数值是整数时,Split后只会得到一个元素,直接取TempSplit(1)会报错,需要加判断:
Dim DecNumber As Double Dim TempSplit() As String Dim DecFract As Double DecNumber = 15.1 TempSplit = Split(CStr(DecNumber), ".") If UBound(TempSplit) = 1 Then DecFract = TempSplit(1) / (10 ^ Len(TempSplit(1))) Else DecFract = 0 ' 整数的小数部分为0 End If
测试代码对比
Dim DecNumber As Double Dim TempSplit() As String Dim DecFract As Double DecNumber = 15.1 'METHOD 1 - 原方法(因浮点数精度出现异常) 'DecFract = DecNumber - Int(DecNumber) 'METHOD 2 - 修正后的字符串拆分法 TempSplit = Split(CStr(DecNumber), ".") If UBound(TempSplit) = 1 Then DecFract = TempSplit(1) / (10 ^ Len(TempSplit(1))) Else DecFract = 0 End If 'METHOD 3 - Decimal转换法 'DecFract = CDec(DecNumber) - Int(CDec(DecNumber))
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

