You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

61 lines
2.2 KiB

  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. import (
  26. "math"
  27. )
  28. // minNormalFloat64 is the smallest positive normal value of type float64.
  29. var minNormalFloat64 = math.Float64frombits(0x0010000000000000)
  30. // AlmostEqualFloat64 returns true if a and b are equal within a relative error
  31. // of epsilon. See http://floating-point-gui.de/errors/comparison/ for the
  32. // details of the applied method.
  33. func AlmostEqualFloat64(a, b, epsilon float64) bool {
  34. if a == b {
  35. return true
  36. }
  37. absA := math.Abs(a)
  38. absB := math.Abs(b)
  39. diff := math.Abs(a - b)
  40. if a == 0 || b == 0 || absA+absB < minNormalFloat64 {
  41. return diff < epsilon*minNormalFloat64
  42. }
  43. return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon
  44. }
  45. // AlmostEqualFloat64s is the slice form of AlmostEqualFloat64.
  46. func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool {
  47. if len(a) != len(b) {
  48. return false
  49. }
  50. for i := range a {
  51. if !AlmostEqualFloat64(a[i], b[i], epsilon) {
  52. return false
  53. }
  54. }
  55. return true
  56. }