See Release Notes
Long Term Support Release
Differences Between: [Versions 400 and 401]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering; 4 5 use PhpOffice\PhpSpreadsheet\Calculation\Exception; 6 use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; 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 array|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 * Or can be an array of values 36 * @param array|int $places The number of characters to use. If places is omitted, DEC2BIN uses 37 * the minimum number of characters necessary. Places is useful for 38 * padding the return value with leading 0s (zeros). 39 * If places is not an integer, it is truncated. 40 * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. 41 * If places is zero or negative, DEC2BIN returns the #NUM! error value. 42 * Or can be an array of values 43 * 44 * @return array|string Result, or an error 45 * If an array of numbers is passed as an argument, then the returned result will also be an array 46 * with the same dimensions 47 */ 48 public static function toBinary($value, $places = null) 49 { 50 if (is_array($value) || is_array($places)) { 51 return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); 52 } 53 54 try { 55 $value = self::validateValue($value); 56 $value = self::validateDecimal($value); 57 $places = self::validatePlaces($places); 58 } catch (Exception $e) { 59 return $e->getMessage(); 60 } 61 62 $value = (int) floor((float) $value); 63 if ($value > self::LARGEST_BINARY_IN_DECIMAL || $value < self::SMALLEST_BINARY_IN_DECIMAL) { 64 return ExcelError::NAN(); 65 } 66 67 $r = decbin($value); 68 // Two's Complement 69 $r = substr($r, -10); 70 71 return self::nbrConversionFormat($r, $places); 72 } 73 74 /** 75 * toHex. 76 * 77 * Return a decimal value as hex. 78 * 79 * Excel Function: 80 * DEC2HEX(x[,places]) 81 * 82 * @param array|string $value The decimal integer you want to convert. If number is negative, 83 * places is ignored and DEC2HEX returns a 10-character (40-bit) 84 * hexadecimal number in which the most significant bit is the sign 85 * bit. The remaining 39 bits are magnitude bits. Negative numbers 86 * are represented using two's-complement notation. 87 * If number < -549,755,813,888 or if number > 549,755,813,887, 88 * DEC2HEX returns the #NUM! error value. 89 * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. 90 * If DEC2HEX requires more than places characters, it returns the 91 * #NUM! error value. 92 * Or can be an array of values 93 * @param array|int $places The number of characters to use. If places is omitted, DEC2HEX uses 94 * the minimum number of characters necessary. Places is useful for 95 * padding the return value with leading 0s (zeros). 96 * If places is not an integer, it is truncated. 97 * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. 98 * If places is zero or negative, DEC2HEX returns the #NUM! error value. 99 * Or can be an array of values 100 * 101 * @return array|string Result, or an error 102 * If an array of numbers is passed as an argument, then the returned result will also be an array 103 * with the same dimensions 104 */ 105 public static function toHex($value, $places = null) 106 { 107 if (is_array($value) || is_array($places)) { 108 return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); 109 } 110 111 try { 112 $value = self::validateValue($value); 113 $value = self::validateDecimal($value); 114 $places = self::validatePlaces($places); 115 } catch (Exception $e) { 116 return $e->getMessage(); 117 } 118 119 $value = floor((float) $value); 120 if ($value > self::LARGEST_HEX_IN_DECIMAL || $value < self::SMALLEST_HEX_IN_DECIMAL) { 121 return ExcelError::NAN(); 122 } 123 $r = strtoupper(dechex((int) $value)); 124 $r = self::hex32bit($value, $r); 125 126 return self::nbrConversionFormat($r, $places); 127 } 128 129 public static function hex32bit(float $value, string $hexstr, bool $force = false): string 130 { 131 if (PHP_INT_SIZE === 4 || $force) { 132 if ($value >= 2 ** 32) { 133 $quotient = (int) ($value / (2 ** 32)); 134 135 return strtoupper(substr('0' . dechex($quotient), -2) . $hexstr); 136 } 137 if ($value < -(2 ** 32)) { 138 $quotient = 256 - (int) ceil((-$value) / (2 ** 32)); 139 140 return strtoupper(substr('0' . dechex($quotient), -2) . substr("00000000$hexstr", -8)); 141 } 142 if ($value < 0) { 143 return "FF$hexstr"; 144 } 145 } 146 147 return $hexstr; 148 } 149 150 /** 151 * toOctal. 152 * 153 * Return an decimal value as octal. 154 * 155 * Excel Function: 156 * DEC2OCT(x[,places]) 157 * 158 * @param array|string $value The decimal integer you want to convert. If number is negative, 159 * places is ignored and DEC2OCT returns a 10-character (30-bit) 160 * octal number in which the most significant bit is the sign bit. 161 * The remaining 29 bits are magnitude bits. Negative numbers are 162 * represented using two's-complement notation. 163 * If number < -536,870,912 or if number > 536,870,911, DEC2OCT 164 * returns the #NUM! error value. 165 * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. 166 * If DEC2OCT requires more than places characters, it returns the 167 * #NUM! error value. 168 * Or can be an array of values 169 * @param array|int $places The number of characters to use. If places is omitted, DEC2OCT uses 170 * the minimum number of characters necessary. Places is useful for 171 * padding the return value with leading 0s (zeros). 172 * If places is not an integer, it is truncated. 173 * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. 174 * If places is zero or negative, DEC2OCT returns the #NUM! error value. 175 * Or can be an array of values 176 * 177 * @return array|string Result, or an error 178 * If an array of numbers is passed as an argument, then the returned result will also be an array 179 * with the same dimensions 180 */ 181 public static function toOctal($value, $places = null) 182 { 183 if (is_array($value) || is_array($places)) { 184 return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places); 185 } 186 187 try { 188 $value = self::validateValue($value); 189 $value = self::validateDecimal($value); 190 $places = self::validatePlaces($places); 191 } catch (Exception $e) { 192 return $e->getMessage(); 193 } 194 195 $value = (int) floor((float) $value); 196 if ($value > self::LARGEST_OCTAL_IN_DECIMAL || $value < self::SMALLEST_OCTAL_IN_DECIMAL) { 197 return ExcelError::NAN(); 198 } 199 $r = decoct($value); 200 $r = substr($r, -10); 201 202 return self::nbrConversionFormat($r, $places); 203 } 204 205 protected static function validateDecimal(string $value): string 206 { 207 if (strlen($value) > preg_match_all('/[-0123456789.]/', $value)) { 208 throw new Exception(ExcelError::VALUE()); 209 } 210 211 return $value; 212 } 213 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body