Fix float64 comparison test failure on archs using FMA (#1133) · prometheus/client_golang@4d54769 (original) (raw)

``

1

`+

// Copyright (c) 2015 Björn Rabenstein

`

``

2

`+

//

`

``

3

`+

// Permission is hereby granted, free of charge, to any person obtaining a copy

`

``

4

`+

// of this software and associated documentation files (the "Software"), to deal

`

``

5

`+

// in the Software without restriction, including without limitation the rights

`

``

6

`+

// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

`

``

7

`+

// copies of the Software, and to permit persons to whom the Software is

`

``

8

`+

// furnished to do so, subject to the following conditions:

`

``

9

`+

//

`

``

10

`+

// The above copyright notice and this permission notice shall be included in all

`

``

11

`+

// copies or substantial portions of the Software.

`

``

12

`+

//

`

``

13

`+

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

`

``

14

`+

// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

`

``

15

`+

// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

`

``

16

`+

// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

`

``

17

`+

// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

`

``

18

`+

// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

`

``

19

`+

// SOFTWARE.

`

``

20

`+

//

`

``

21

`+

// The code in this package is copy/paste to avoid a dependency. Hence this file

`

``

22

`+

// carries the copyright of the original repo.

`

``

23

`+

// https://github.com/beorn7/floats

`

``

24

`+

package internal

`

``

25

+

``

26

`+

import (

`

``

27

`+

"math"

`

``

28

`+

)

`

``

29

+

``

30

`+

// minNormalFloat64 is the smallest positive normal value of type float64.

`

``

31

`+

var minNormalFloat64 = math.Float64frombits(0x0010000000000000)

`

``

32

+

``

33

`+

// AlmostEqualFloat64 returns true if a and b are equal within a relative error

`

``

34

`+

// of epsilon. See http://floating-point-gui.de/errors/comparison/ for the

`

``

35

`+

// details of the applied method.

`

``

36

`+

func AlmostEqualFloat64(a, b, epsilon float64) bool {

`

``

37

`+

if a == b {

`

``

38

`+

return true

`

``

39

`+

}

`

``

40

`+

absA := math.Abs(a)

`

``

41

`+

absB := math.Abs(b)

`

``

42

`+

diff := math.Abs(a - b)

`

``

43

`+

if a == 0 || b == 0 || absA+absB < minNormalFloat64 {

`

``

44

`+

return diff < epsilon*minNormalFloat64

`

``

45

`+

}

`

``

46

`+

return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon

`

``

47

`+

}

`

``

48

+

``

49

`+

// AlmostEqualFloat64s is the slice form of AlmostEqualFloat64.

`

``

50

`+

func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool {

`

``

51

`+

if len(a) != len(b) {

`

``

52

`+

return false

`

``

53

`+

}

`

``

54

`+

for i := range a {

`

``

55

`+

if !AlmostEqualFloat64(a[i], b[i], epsilon) {

`

``

56

`+

return false

`

``

57

`+

}

`

``

58

`+

}

`

``

59

`+

return true

`

``

60

`+

}

`