std :: fmod4.2,0.12等于epsilon * 1.5

问题描述

Private Sub CommandButton2_Click()
Dim Dic As Object,key As Variant,oCell As Range,i&
Dim w1 As Worksheet,w2 As Worksheet
Dim cell As Range
Dim SrchRng As Range

Set Dic = CreateObject("Scripting.Dictionary")
Set w1 = Workbooks("HF Pricing Template1").Sheets("Tables")
Set w2 = Workbooks("Book1").Sheets("Sheet1")
Set SrchRng = Range("Table3[Price_Type]")

For Each cell In SrchRng
If cell.Value = "P" Then

i = w1.Cells.SpecialCells(xlCellTypeLastCell).Row

    For Each oCell In w1.Range("M5:M" & i)
        If Not Dic.exists(oCell.Value) Then
            Dic.Add oCell.Value,oCell.Offset(,5).Value
        End If
    Next


 i = w2.Cells.SpecialCells(xlCellTypeLastCell).Row

    For Each oCell In w2.Range("A2:A" & i)
        For Each key In Dic
            If oCell.Value = key Then
                oCell.Offset(,3).Value = Dic(key)
            End If
        Next
    Next
End If

Next cell
For Each cell In SrchRng
If cell.Value = "P" Then

   i = w1.Cells.SpecialCells(xlCellTypeLastCell).Row

    For Each oCell In w1.Range("M5:M" & i)
        If Not Dic.exists(oCell.Value) Then
            Dic.Add oCell.Value,5).Value
        End If
    Next


    i = w2.Cells.SpecialCells(xlCellTypeLastCell).Row

    For Each oCell In w2.Range("A2:A" & i)
        For Each key In Dic
            If oCell.Value = key Then
                oCell.Offset(,4).Value = Dic(key)
            End If
        Next
    Next
 End If

 Next cell

End Sub

在此示例中,由于auto a{ 4.2 }; auto b{ 0.12 }; auto result = std::fmod(a,b); if(result <= std::numeric_limits<double>::epsilon()) result = 0; // <-- This line isn't triggered 不精确,因此4.2实际上等于4.2000000000000002

请注意,4.2 / 0.12 = 35。

我希望输出等于double。相反,结果等于std::numeric_limits<double>::epsilon()

1.5乘数来自哪里?

解决方法

可以预期std::fmod的结果在ULP左右范围内是准确的,但是机器epsilon是1的ULP,而不是任何给定操作的结果。