github.com/searKing/golang/go@v1.2.117/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 // 17 // the maximum n bits precision. 18 // 19 // case n < 0 20 // 21 // -n bits of the magnitude of x trunked 22 // 23 // Special cases are: 24 // 25 // Trunc(±0) = ±0 26 // Trunc(±Inf) = ±Inf 27 // Trunc(NaN) = NaN 28 func TruncPrecision(x float64, n int) float64 { 29 n10 := math.Pow10(n) 30 return math.Copysign(math.Trunc((math.Abs(x)+0.5/n10)*n10)/n10, x) 31 } 32 33 // Tolerance returns true if |a-b| < e 34 // e usually can be set with Epsilon(1e-6) 35 func Tolerance(a, b, e float64) bool { 36 // Multiplying by e here can underflow denormal values to zero. 37 // Check a==b so that at least if a and b are small and identical 38 // we say they match. 39 if a == b { 40 return true 41 } 42 d := a - b 43 if d < 0 { 44 d = -d 45 } 46 47 // note: b is correct (expected) value, a is actual value. 48 // make error tolerance a fraction of b, not a. 49 if b != 0 { 50 e = e * b 51 if e < 0 { 52 e = -e 53 } 54 } 55 return d < e 56 } 57 58 // Close returns true if |a-b| < 1e14 59 func Close(a, b float64) bool { return Tolerance(a, b, EpsilonClose) } 60 61 // VeryClose returns true if |a-b| < 1e16 62 func VeryClose(a, b float64) bool { return Tolerance(a, b, EpsilonVeryClose) } 63 64 // SoClose is an alias of Tolerance 65 func SoClose(a, b, e float64) bool { return Tolerance(a, b, e) } 66 67 // Alike returns true if a,b is the same exactly (no tolerance) or both NaN 68 func Alike(a, b float64) bool { 69 switch { 70 case math.IsNaN(a) && math.IsNaN(b): 71 return true 72 case a == b: 73 return math.Signbit(a) == math.Signbit(b) 74 } 75 return false 76 }