Ejemplo n.º 1
0
 /**
  * Determines if the supplied double fits into this float as a subnormal.
  *
  * @param Float64 $float The float (represented in 64 bit).
  * @return boolean Whether the double fits as a subnormal inside this float type.
  */
 public static function fitsAsSubnormal(Float64 $float)
 {
     // If the exponent is lower than the lowest subnormal, it can't fit
     if ($float->getExponent() < 1 - static::getExponentOffset() - static::getNumSignificandBits()) {
         return false;
     }
     // If the exponent is larger than the negative exponent offset, it can't fit
     if ($float->getExponent() > 1 - static::getExponentOffset()) {
         return false;
     }
     // Make sure the significand (+1 implicit digit) actually fits in the required number of bits
     if (($float->getSignificand() << 1) + 1 > self::getMaxSignificand()) {
         return false;
     }
     // Trash all the trailing zeros in the significand
     $significand = $float->getSignificand();
     // Convert the significand into a binary string
     $significand = decbin($significand);
     // Trim leading zeros
     $significand = ltrim($significand, '0');
     // Add a 1 to the start of the string, it's implicit in normal numbers, but not in subnormals
     $significand = bindec('1' . $significand);
     // Determine the number of "exponent bits" you have free
     $exponentBits = static::getNumSignificandBits() - strlen($significand);
     // Compute the minimum exponent you can do with those free bits
     $minExponent = -1 * (static::getExponentOffset() + $exponentBits);
     // If the exponent fits
     return $float->getExponent() >= $minExponent;
 }
Ejemplo n.º 2
0
 /**
  * Decodes a double value.
  *
  * @param int $length Size of the number, in bytes.
  * @param array $bytes The messages byte array.
  * @return float The decoded double.
  * @throws CborException If there aren't enough bytes in the remaining byte string.
  */
 private static function decodeDouble($length, &$bytes)
 {
     // Not enough bytes
     if ($length > count($bytes)) {
         throw new CborException("The supplied byte string is too short to decode the specified double type.");
     }
     // Grab the required number of bytes
     $byteArray = array_splice($bytes, 0, $length);
     // Unpack a 32 bit double
     if ($length == 4) {
         return Float32::decode($byteArray);
     } else {
         if ($length == 8) {
             return Float64::decode($byteArray);
         } else {
             return Float16::decode($byteArray);
         }
     }
 }