AsymUp函数(舍入)不能产生预期的结果 - VB6

时间:2014-12-24 20:16:04

标签: vb6 rounding

我正在尝试将我在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,暗示该功能运作不佳。

如何纠正此问题以实现预期效果

3 个答案:

答案 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后的情况。