Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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 ConvertHex extends ConvertBase
   9  {
  10      /**
  11       * toBinary.
  12       *
  13       * Return a hex value as binary.
  14       *
  15       * Excel Function:
  16       *        HEX2BIN(x[,places])
  17       *
  18       * @param array|string $value The hexadecimal number you want to convert.
  19       *                      Number cannot contain more than 10 characters.
  20       *                      The most significant bit of number is the sign bit (40th bit from the right).
  21       *                      The remaining 9 bits are magnitude bits.
  22       *                      Negative numbers are represented using two's-complement notation.
  23       *                      If number is negative, HEX2BIN ignores places and returns a 10-character binary number.
  24       *                      If number is negative, it cannot be less than FFFFFFFE00,
  25       *                          and if number is positive, it cannot be greater than 1FF.
  26       *                      If number is not a valid hexadecimal number, HEX2BIN returns the #NUM! error value.
  27       *                      If HEX2BIN requires more than places characters, it returns the #NUM! error value.
  28       *                      Or can be an array of values
  29       * @param array|int $places The number of characters to use. If places is omitted,
  30       *                          HEX2BIN uses the minimum number of characters necessary. Places
  31       *                          is useful for padding the return value with leading 0s (zeros).
  32       *                      If places is not an integer, it is truncated.
  33       *                      If places is nonnumeric, HEX2BIN returns the #VALUE! error value.
  34       *                      If places is negative, HEX2BIN returns the #NUM! error value.
  35       *                      Or can be an array of values
  36       *
  37       * @return array|string Result, or an error
  38       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  39       *            with the same dimensions
  40       */
  41      public static function toBinary($value, $places = null)
  42      {
  43          if (is_array($value) || is_array($places)) {
  44              return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places);
  45          }
  46  
  47          try {
  48              $value = self::validateValue($value);
  49              $value = self::validateHex($value);
  50              $places = self::validatePlaces($places);
  51          } catch (Exception $e) {
  52              return $e->getMessage();
  53          }
  54  
  55          $dec = self::toDecimal($value);
  56  
  57          return ConvertDecimal::toBinary($dec, $places);
  58      }
  59  
  60      /**
  61       * toDecimal.
  62       *
  63       * Return a hex value as decimal.
  64       *
  65       * Excel Function:
  66       *        HEX2DEC(x)
  67       *
  68       * @param array|string $value The hexadecimal number you want to convert. This number cannot
  69       *                          contain more than 10 characters (40 bits). The most significant
  70       *                          bit of number is the sign bit. The remaining 39 bits are magnitude
  71       *                          bits. Negative numbers are represented using two's-complement
  72       *                          notation.
  73       *                      If number is not a valid hexadecimal number, HEX2DEC returns the
  74       *                          #NUM! error value.
  75       *                      Or can be an array of values
  76       *
  77       * @return array|string Result, or an error
  78       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  79       *            with the same dimensions
  80       */
  81      public static function toDecimal($value)
  82      {
  83          if (is_array($value)) {
  84              return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
  85          }
  86  
  87          try {
  88              $value = self::validateValue($value);
  89              $value = self::validateHex($value);
  90          } catch (Exception $e) {
  91              return $e->getMessage();
  92          }
  93  
  94          if (strlen($value) > 10) {
  95              return ExcelError::NAN();
  96          }
  97  
  98          $binX = '';
  99          foreach (str_split($value) as $char) {
 100              $binX .= str_pad(base_convert($char, 16, 2), 4, '0', STR_PAD_LEFT);
 101          }
 102          if (strlen($binX) == 40 && $binX[0] == '1') {
 103              for ($i = 0; $i < 40; ++$i) {
 104                  $binX[$i] = ($binX[$i] == '1' ? '0' : '1');
 105              }
 106  
 107              return (string) ((bindec($binX) + 1) * -1);
 108          }
 109  
 110          return (string) bindec($binX);
 111      }
 112  
 113      /**
 114       * toOctal.
 115       *
 116       * Return a hex value as octal.
 117       *
 118       * Excel Function:
 119       *        HEX2OCT(x[,places])
 120       *
 121       * @param array|string $value The hexadecimal number you want to convert. Number cannot
 122       *                                    contain more than 10 characters. The most significant bit of
 123       *                                    number is the sign bit. The remaining 39 bits are magnitude
 124       *                                    bits. Negative numbers are represented using two's-complement
 125       *                                    notation.
 126       *                                    If number is negative, HEX2OCT ignores places and returns a
 127       *                                    10-character octal number.
 128       *                                    If number is negative, it cannot be less than FFE0000000, and
 129       *                                    if number is positive, it cannot be greater than 1FFFFFFF.
 130       *                                    If number is not a valid hexadecimal number, HEX2OCT returns
 131       *                                    the #NUM! error value.
 132       *                                    If HEX2OCT requires more than places characters, it returns
 133       *                                    the #NUM! error value.
 134       *                      Or can be an array of values
 135       * @param array|int $places The number of characters to use. If places is omitted, HEX2OCT
 136       *                                    uses the minimum number of characters necessary. Places is
 137       *                                    useful for padding the return value with leading 0s (zeros).
 138       *                                    If places is not an integer, it is truncated.
 139       *                                    If places is nonnumeric, HEX2OCT returns the #VALUE! error
 140       *                                    value.
 141       *                                    If places is negative, HEX2OCT returns the #NUM! error value.
 142       *                      Or can be an array of values
 143       *
 144       * @return array|string Result, or an error
 145       *         If an array of numbers is passed as an argument, then the returned result will also be an array
 146       *            with the same dimensions
 147       */
 148      public static function toOctal($value, $places = null)
 149      {
 150          if (is_array($value) || is_array($places)) {
 151              return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places);
 152          }
 153  
 154          try {
 155              $value = self::validateValue($value);
 156              $value = self::validateHex($value);
 157              $places = self::validatePlaces($places);
 158          } catch (Exception $e) {
 159              return $e->getMessage();
 160          }
 161  
 162          $decimal = self::toDecimal($value);
 163  
 164          return ConvertDecimal::toOctal($decimal, $places);
 165      }
 166  
 167      protected static function validateHex(string $value): string
 168      {
 169          if (strlen($value) > preg_match_all('/[0123456789ABCDEF]/', $value)) {
 170              throw new Exception(ExcelError::NAN());
 171          }
 172  
 173          return $value;
 174      }
 175  }