2010-09-07 156 views
3

在VB6中測試兩個單方相等的最佳方式是什麼?在VB6中的浮點比較

我想測試兩個單值的平等爲7有效數字。

This MSDN article建議使用類似

If Abs(a - b) <= Abs(a/10^7) Then 
    valuesEqual = True 
End If 

然而,可爲失敗的某些值,例如

Public Sub Main() 

    Dim a As Single 
    Dim b As Single 

    a = 0.50000005 
    b = 0.50000014 

    Debug.Print "a = " & a 
    Debug.Print "b = " & b 
    Debug.Print "a = b: " & (a = b) 
    Debug.Print "SinglesAreEqual(a, b): " & SinglesAreEqual(a, b) 

    // Output: 
    // a = 0.5000001 
    // b = 0.5000001 
    // b = b: False 
    // SinglesAreEqual(a, b): False 

End Sub 

Private Function SinglesAreEqual(a As Single, b As Single) As Boolean 

    If Abs(a - b) <= Abs(a/10^7) Then 
     SinglesAreEqual = True 
    Else 
     SinglesAreEqual = False 
    End If 

End Function 

我發現得到的結果,我需要最簡單的方法是將值轉換爲字符串,但似乎可怕的醜陋:

Private Function SinglesAreEqual(a As Single, b As Single) As Boolean 

    SinglesAreEqual = (Str$(a) = Str$(b)) 

End Function 

有什麼更好的辦法?

+0

我覺得這裏的主要問題是認爲單持有十進制數據。這使得諸如「7位有效數字」的概念受到轉換和近似誤差的影響。在執行您引用的比較計算之前,您可以嘗試將它們轉換爲Double值。 – Bob77 2010-09-07 16:03:55

+0

Bob - a Single是4字節的浮點值,Double是8字節的浮點數,所以有意義的數字是相關的。十進制數據保存在十進制數據類型中。 – roomaroo 2010-09-08 11:48:30

+0

否Variant的「Decimal」子類型與Currency相同,是一個縮放的二進制整數。你的「7位數字」是「7位十進制數字」,並且由於Single保存二進制數據,這就是錯誤蔓延的地方。也許看看http://msdn.microsoft.com/en-us/library/aa164504(office.10) ).aspx爲了一些清晰? 「7位數字」正在推動Single的準確性限制。 – Bob77 2010-09-10 04:14:42

回答

3

我維護一個CAD/CAM應用程序,我必須一直處理浮點數。我有一個函數,我稱之爲fComp,當我需要測試相等性時,我傳遞了一個浮點值。 fComp調用設置爲一定精度的舍入函數。對於我們的系統,我舍入到小數點後6位。你可能需要更高的價格,或者更低的價格取決於應用。

fComp函數存在,所以我有一個地方可以改變這些計算中使用的舍入因子。幾年前,當我們開始生產更高精度的機器時,這證明很方便。

Public Function pRound(ByVal Value As Double, ByVal Power As Double) As Double 
    Dim TempValue As Double 
    Dim tSign As Double 
    TempValue = Value 
    tSign = TempValue 
    TempValue = Abs(TempValue) 
    TempValue = TempValue * 10^(Power * -1) 
    TempValue = Fix(TempValue + 0.5) 
    TempValue = TempValue/10^(Power * -1) 
    pRound = TempValue * Sign(tSign) 
End Function 

舍入到第6位小數你去

RoundedNumber =驕傲(myvalue的,-6)

負是小數位正向左右側。

+0

謝謝,但我需要四捨五入到一定數量的有效數字,而不是小數位 - 123.456789應舍入爲123.4568,但1.23456789應舍入爲1.234568 – roomaroo 2010-09-07 14:05:05

2

相反,如果四捨五入和測試平等,你可以採取兩個數字的差異和比較,有一個因素

If Abs(a - b) < 0.000001 Then

您可以調整0.000001到任何決議需要

2

我不相信你可以使用single數據類型到許多有效數字。您可能需要使用double代替:

Dim a As Single 
Dim s As String 

s = "0.50000005" 
a = 0.50000005 

Debug.Print s & " " & a 

以上輸出:

0.50000005 
0.5000001 
+0

在即時窗口「4.2 - 0.1 = 4.1」中嘗試此操作。由於計算機處理重複數字的方式,它將返回錯誤。您可以在python idle或vb.net immediate窗口中嘗試「4.2 - 0.1」來查看返回的內容。另見http://docs.sun.com/source/806-3568/ncg_goldberg.html – bugtussle 2010-09-09 15:38:38