Floats.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. /**
  3. * This file is part of the Nette Framework (https://nette.org)
  4. * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  5. */
  6. declare(strict_types=1);
  7. namespace Nette\Utils;
  8. use Nette;
  9. /**
  10. * Floating-point numbers comparison.
  11. */
  12. class Floats
  13. {
  14. use Nette\StaticClass;
  15. private const EPSILON = 1e-10;
  16. public static function isZero(float $value): bool
  17. {
  18. return abs($value) < self::EPSILON;
  19. }
  20. public static function isInteger(float $value): bool
  21. {
  22. return abs(round($value) - $value) < self::EPSILON;
  23. }
  24. /**
  25. * Compare two floats. If $a < $b it returns -1, if they are equal it returns 0 and if $a > $b it returns 1
  26. * @throws \LogicException if one of parameters is NAN
  27. */
  28. public static function compare(float $a, float $b): int
  29. {
  30. if (is_nan($a) || is_nan($b)) {
  31. throw new \LogicException('Trying to compare NAN');
  32. } elseif (!is_finite($a) && !is_finite($b) && $a === $b) {
  33. return 0;
  34. }
  35. $diff = abs($a - $b);
  36. if (($diff < self::EPSILON || ($diff / max(abs($a), abs($b)) < self::EPSILON))) {
  37. return 0;
  38. }
  39. return $a < $b ? -1 : 1;
  40. }
  41. /**
  42. * Returns true if $a = $b
  43. * @throws \LogicException if one of parameters is NAN
  44. */
  45. public static function areEqual(float $a, float $b): bool
  46. {
  47. return self::compare($a, $b) === 0;
  48. }
  49. /**
  50. * Returns true if $a < $b
  51. * @throws \LogicException if one of parameters is NAN
  52. */
  53. public static function isLessThan(float $a, float $b): bool
  54. {
  55. return self::compare($a, $b) < 0;
  56. }
  57. /**
  58. * Returns true if $a <= $b
  59. * @throws \LogicException if one of parameters is NAN
  60. */
  61. public static function isLessThanOrEqualTo(float $a, float $b): bool
  62. {
  63. return self::compare($a, $b) <= 0;
  64. }
  65. /**
  66. * Returns true if $a > $b
  67. * @throws \LogicException if one of parameters is NAN
  68. */
  69. public static function isGreaterThan(float $a, float $b): bool
  70. {
  71. return self::compare($a, $b) > 0;
  72. }
  73. /**
  74. * Returns true if $a >= $b
  75. * @throws \LogicException if one of parameters is NAN
  76. */
  77. public static function isGreaterThanOrEqualTo(float $a, float $b): bool
  78. {
  79. return self::compare($a, $b) >= 0;
  80. }
  81. }