Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; 4 5 use PhpOffice\PhpSpreadsheet\Calculation\Exception; 6 use PhpOffice\PhpSpreadsheet\Calculation\Functions; 7 8 class ConvertDecimal extends ConvertBase 9 { 10 const LARGEST_OCTAL_IN_DECIMAL = 536870911; 11 const SMALLEST_OCTAL_IN_DECIMAL = -536870912; 12 const LARGEST_BINARY_IN_DECIMAL = 511; 13 const SMALLEST_BINARY_IN_DECIMAL = -512; 14 const LARGEST_HEX_IN_DECIMAL = 549755813887; 15 const SMALLEST_HEX_IN_DECIMAL = -549755813888; 16 17 /** 18 * toBinary. 19 * 20 * Return a decimal value as binary. 21 * 22 * Excel Function: 23 * DEC2BIN(x[,places]) 24 * 25 * @param string $value The decimal integer you want to convert. If number is negative, 26 * valid place values are ignored and DEC2BIN returns a 10-character 27 * (10-bit) binary number in which the most significant bit is the sign 28 * bit. The remaining 9 bits are magnitude bits. Negative numbers are 29 * represented using two's-complement notation. 30 * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error 31 * value. 32 * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. 33 * If DEC2BIN requires more than places characters, it returns the #NUM! 34 * error value. 35 * @param int $places The number of characters to use. If places is omitted, DEC2BIN uses 36 * the minimum number of characters necessary. Places is useful for 37 * padding the return value with leading 0s (zeros). 38 * If places is not an integer, it is truncated. 39 * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. 40 * If places is zero or negative, DEC2BIN returns the #NUM! error value. 41 */ 42 public static function toBinary($value, $places = null): string 43 { 44 try { 45 $value = self::validateValue(Functions::flattenSingleValue($value)); 46 $value = self::validateDecimal($value); 47 $places = self::validatePlaces(Functions::flattenSingleValue($places)); 48 } catch (Exception $e) { 49 return $e->getMessage(); 50 } 51 52 $value = (int) floor((float) $value); 53 if ($value > self::LARGEST_BINARY_IN_DECIMAL || $value < self::SMALLEST_BINARY_IN_DECIMAL) { 54 return Functions::NAN(); 55 } 56 57 $r = decbin($value); 58 // Two's Complement 59 $r = substr($r, -10); 60 61 return self::nbrConversionFormat($r, $places); 62 } 63 64 /** 65 * toHex. 66 * 67 * Return a decimal value as hex. 68 * 69 * Excel Function: 70 * DEC2HEX(x[,places]) 71 * 72 * @param string $value The decimal integer you want to convert. If number is negative, 73 * places is ignored and DEC2HEX returns a 10-character (40-bit) 74 * hexadecimal number in which the most significant bit is the sign 75 * bit. The remaining 39 bits are magnitude bits. Negative numbers 76 * are represented using two's-complement notation. 77 * If number < -549,755,813,888 or if number > 549,755,813,887, 78 * DEC2HEX returns the #NUM! error value. 79 * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. 80 * If DEC2HEX requires more than places characters, it returns the 81 * #NUM! error value. 82 * @param int $places The number of characters to use. If places is omitted, DEC2HEX uses 83 * the minimum number of characters necessary. Places is useful for 84 * padding the return value with leading 0s (zeros). 85 * If places is not an integer, it is truncated. 86 * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. 87 * If places is zero or negative, DEC2HEX returns the #NUM! error value. 88 */ 89 public static function toHex($value, $places = null): string 90 { 91 try { 92 $value = self::validateValue(Functions::flattenSingleValue($value)); 93 $value = self::validateDecimal($value); 94 $places = self::validatePlaces(Functions::flattenSingleValue($places)); 95 } catch (Exception $e) { 96 return $e->getMessage(); 97 } 98 99 $value = floor((float) $value); 100 if ($value > self::LARGEST_HEX_IN_DECIMAL || $value < self::SMALLEST_HEX_IN_DECIMAL) { 101 return Functions::NAN(); 102 } 103 $r = strtoupper(dechex((int) $value)); 104 $r = self::hex32bit($value, $r); 105 106 return self::nbrConversionFormat($r, $places); 107 } 108 109 public static function hex32bit(float $value, string $hexstr, bool $force = false): string 110 { 111 if (PHP_INT_SIZE === 4 || $force) { 112 if ($value >= 2 ** 32) { 113 $quotient = (int) ($value / (2 ** 32)); 114 115 return strtoupper(substr('0' . dechex($quotient), -2) . $hexstr); 116 } 117 if ($value < -(2 ** 32)) { 118 $quotient = 256 - (int) ceil((-$value) / (2 ** 32)); 119 120 return strtoupper(substr('0' . dechex($quotient), -2) . substr("00000000$hexstr", -8)); 121 } 122 if ($value < 0) { 123 return "FF$hexstr"; 124 } 125 } 126 127 return $hexstr; 128 } 129 130 /** 131 * toOctal. 132 * 133 * Return an decimal value as octal. 134 * 135 * Excel Function: 136 * DEC2OCT(x[,places]) 137 * 138 * @param string $value The decimal integer you want to convert. If number is negative, 139 * places is ignored and DEC2OCT returns a 10-character (30-bit) 140 * octal number in which the most significant bit is the sign bit. 141 * The remaining 29 bits are magnitude bits. Negative numbers are 142 * represented using two's-complement notation. 143 * If number < -536,870,912 or if number > 536,870,911, DEC2OCT 144 * returns the #NUM! error value. 145 * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. 146 * If DEC2OCT requires more than places characters, it returns the 147 * #NUM! error value. 148 * @param int $places The number of characters to use. If places is omitted, DEC2OCT uses 149 * the minimum number of characters necessary. Places is useful for 150 * padding the return value with leading 0s (zeros). 151 * If places is not an integer, it is truncated. 152 * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. 153 * If places is zero or negative, DEC2OCT returns the #NUM! error value. 154 */ 155 public static function toOctal($value, $places = null): string 156 { 157 try { 158 $value = self::validateValue(Functions::flattenSingleValue($value)); 159 $value = self::validateDecimal($value); 160 $places = self::validatePlaces(Functions::flattenSingleValue($places)); 161 } catch (Exception $e) { 162 return $e->getMessage(); 163 } 164 165 $value = (int) floor((float) $value); 166 if ($value > self::LARGEST_OCTAL_IN_DECIMAL || $value < self::SMALLEST_OCTAL_IN_DECIMAL) { 167 return Functions::NAN(); 168 } 169 $r = decoct($value); 170 $r = substr($r, -10); 171 172 return self::nbrConversionFormat($r, $places); 173 } 174 175 protected static function validateDecimal(string $value): string 176 { 177 if (strlen($value) > preg_match_all('/[-0123456789.]/', $value)) { 178 throw new Exception(Functions::VALUE()); 179 } 180 181 return $value; 182 } 183 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body