github.com/searKing/golang/go@v1.2.74/math/float.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package math 6 7 import "math" 8 9 // Epsilon very small 10 var Epsilon = 1e-6 11 var EpsilonClose = 1e-14 12 var EpsilonVeryClose = 1e-16 13 14 // TruncPrecision returns the float value of x, with 15 // case n >= 0 16 // the maximum n bits precision. 17 // case n < 0 18 // -n bits of the magnitude of x trunked 19 // Special cases are: 20 // Trunc(±0) = ±0 21 // Trunc(±Inf) = ±Inf 22 // Trunc(NaN) = NaN 23 func TruncPrecision(x float64, n int) float64 { 24 n10 := math.Pow10(n) 25 return math.Copysign(math.Trunc((math.Abs(x)+0.5/n10)*n10)/n10, x) 26 } 27 28 // Tolerance returns true if |a-b| < e 29 // e usually can be set with Epsilon(1e-6) 30 func Tolerance(a, b, e float64) bool { 31 // Multiplying by e here can underflow denormal values to zero. 32 // Check a==b so that at least if a and b are small and identical 33 // we say they match. 34 if a == b { 35 return true 36 } 37 d := a - b 38 if d < 0 { 39 d = -d 40 } 41 42 // note: b is correct (expected) value, a is actual value. 43 // make error tolerance a fraction of b, not a. 44 if b != 0 { 45 e = e * b 46 if e < 0 { 47 e = -e 48 } 49 } 50 return d < e 51 } 52 53 // Close returns true if |a-b| < 1e14 54 func Close(a, b float64) bool { return Tolerance(a, b, EpsilonClose) } 55 56 // VeryClose returns true if |a-b| < 1e16 57 func VeryClose(a, b float64) bool { return Tolerance(a, b, EpsilonVeryClose) } 58 59 // SoClose is an alias of Tolerance 60 func SoClose(a, b, e float64) bool { return Tolerance(a, b, e) } 61 62 // Alike returns true if a,b is the same exactly (no tolerance) or both NaN 63 func Alike(a, b float64) bool { 64 switch { 65 case math.IsNaN(a) && math.IsNaN(b): 66 return true 67 case a == b: 68 return math.Signbit(a) == math.Signbit(b) 69 } 70 return false 71 }