我正在尝试将我在VB6中编码的遗留应用程序中的数字进行舍入,以获得以下结果:
2.53应为2.60
2.55应该是2.60
2.56应为2.60
2.50应保持2.50
2.501应为2.50
2.505应为2.60
我尝试使用Microsoft建议的用户定义舍入功能 http://support.microsoft.com/kb/196652/en-gb
我最接近的是Asymup功能
Function AsymUp(ByVal X As Double, _
Optional ByVal Factor As Double = 1) As Double
Dim Temp As Double
Temp = Int(X * Factor)
AsymUp = (Temp + IIf(X = Temp, 0, 1)) / Factor
End Function
我正在通过调用函数来测试此过程,如下所示:
Text1.Text = AsymUp(Val(Text1.Text), 10)
但是这并没有产生预期的结果,因为当我希望它保持2.6时,例如2.60变为2.7。奇怪的是,2.0也变为2.1,暗示该功能运作不佳。
如何纠正此问题以实现预期效果
答案 0 :(得分:2)
Private Function AsymUp(ByVal D As Double, Optional Precision As Double = 1) As Double
Precision = CDbl("1" & String$(Precision, 48))
D = D * Precision
If Int(D) <> D Then
AsymUp = (Int(D) + 1) / Precision
Else
AsymUp = D / Precision
End If
End Function
Visual Basic将始终自动截断Double和Single数据类型的尾随零。因此,除非将函数设计为将数字作为字符串传递回来,并附加额外的零,否则将无法保留特定精度的尾随零。
奖励提示:在性能受到关注的情况下不应使用IIf函数,因为 falsepart 和 truthpart 参数始终都会被评估,无论传递给他们的论据如何。
答案 1 :(得分:0)
字符串操作方法(保留零):
Private Function AsymUp(ByVal D As Double, Optional Precision As Double = 1) As String
Dim P As Double, Z As Long
P = CDbl("1" & String$(Precision, 48))
D = D * P
If Int(D) <> D Then
D = (Int(D) + 1) / P
Else
D = D / P
End If
AsymUp = CStr(D)
Z = Precision - (Len(AsymUp) - InStr(AsymUp, "."))
If Z > 0 Then AsymUp = AsymUp & String$(Z, 48)
End Function
这显然不如我的其他答案那样有效,但它是保持任何尾随零完整的唯一方法。
请注意,该功能始终将数字作为字符串返回。您可能需要将字符串转换回十进制数,以继续使用程序中带有附加数学的数字。
答案 2 :(得分:0)
我已使用以下代码解决了该问题:
Private Sub Command1_Click()
roundnumber = Val(Text1.Text)
Text1.Text = Round(roundnumber, 2)
Text1.Text = AsymUp(Val(Text1.Text), 10)
End Sub
Function AsymUp(ByVal X As Double, _
Optional ByVal Factor As Double = 1) As Double
Dim Temp As Double
Temp = Int(X * Factor)
AsymUp = (Temp + IIf((X * Factor) = Temp, 0, 1)) / Factor
End Function
这就是我在这篇文章中建议的不精确到10dp后的情况。