Compare floats in php

后端 未结 16 1675
清歌不尽
清歌不尽 2020-11-22 00:47

I want to compare two floats in PHP, like in this sample code:

$a = 0.17;
$b = 1 - 0.83; //0.17
if($a == $b ){
 echo \'a and b are same\';
}
else {
 echo \'a         


        
16条回答
  •  自闭症患者
    2020-11-22 01:21

    Here is a useful class from my personal library for dealing with floating point numbers. You can tweek it to your liking and insert any solution you like into the class methods :-).

    /**
     * A class for dealing with PHP floating point values.
     * 
     * @author Anthony E. Rutledge
     * @version 12-06-2018
     */
    final class Float extends Number
    {
        // PHP 7.4 allows for property type hints!
    
        private const LESS_THAN = -1;
        private const EQUAL = 0;
        private const GREATER_THAN = 1;
    
        public function __construct()
        {
    
        }
    
        /**
         * Determines if a value is an float.
         * 
         * @param mixed $value
         * @return bool
         */
        public function isFloat($value): bool
        {
            return is_float($value);
        }
    
        /**
         * A method that tests to see if two float values are equal.
         * 
         * @param float $y1
         * @param float $y2
         * @return bool
         */
        public function equals(float $y1, float $y2): bool
        {
            return (string) $y1 === (string) $y2;
        }
    
        /**
         * A method that tests to see if two float values are not equal.
         * 
         * @param float $y1
         * @param float $y2
         * @return bool
         */
        public function isNotEqual(float $y1, float $y2): bool
        {
            return !$this->equals($y1, $y2);
        }
    
        /**
         * Gets the bccomp result.
         * 
         * @param float $y1
         * @param float $y2
         * @return int
         */
        private function getBccompResult(float $y1, float $y2): int
        {
            $leftOperand = (string) $y1;
            $rightOperand = (string) $y2;
    
            // You should check the format of the float before using it.
    
            return bccomp($leftOperand, $rightOperand);
        }
    
        /**
         * A method that tests to see if y1 is less than y2.
         * 
         * @param float $y1
         * @param float $y2
         * @return bool
         */
        public function isLess(float $y1, float $y2): bool
        {
            return ($this->getBccompResult($y1, $y2) === self::LESS_THAN);
        }
    
        /**
         * A method that tests to see if y1 is less than or equal to y2.
         * 
         * @param float $y1
         * @param float $y2
         * @return bool
         */
        public function isLessOrEqual(float $y1, float $y2): bool
        {
            $bccompResult = $this->getBccompResult($y1, $y2);
            return ($bccompResult === self::LESS_THAN || $bccompResult === self::EQUALS);
        }
    
        /**
         * A method that tests to see if y1 is greater than y2.
         * 
         * @param float $y1
         * @param float $y2
         * @return bool
         */
        public function isGreater(float $y1, float $y2): bool
        {
            return ($this->getBccompResult($y1, $y2) === self::GREATER_THAN);
        }
    
        /**
         * A method that tests to see if y1 is greater than or equal to y2.
         * 
         * @param float $y1
         * @param float $y2
         * @return bool
         */
        public function isGreaterOrEqual(float $y1, float $y2): bool
        {
            $bccompResult = $this->getBccompResult($y1, $y2);
            return ($bccompResult === self::GREATER_THAN || $bccompResult === self::EQUALS);
        }
    
        /**
         * Returns a valid PHP float value, casting if necessary.
         * 
         * @param mixed $value
         * @return float
         *
         * @throws InvalidArgumentException
         * @throws UnexpectedValueException
         */
        public function getFloat($value): float
        {
            if (! (is_string($value) || is_int($value) || is_bool($value))) {
                throw new InvalidArgumentException("$value should not be converted to float!");
            }
    
            if ($this->isFloat($value)) {
                return $value;
            }
    
            $newValue = (float) $value;
    
            if ($this->isNan($newValue)) {
                throw new UnexpectedValueException("The value $value was converted to NaN!");
            }
    
            if (!$this->isNumber($newValue)) {
                throw new UnexpectedValueException("The value $value was converted to something non-numeric!");
            }
    
            if (!$this->isFLoat($newValue)) {
                throw new UnexpectedValueException("The value $value was not converted to a floating point value!");
            }
    
            return $newValue;
        }
    }
    ?>
    

提交回复
热议问题