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] [Versions 401 and 403]

   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 ConvertBinary extends ConvertBase
   9  {
  10      /**
  11       * toDecimal.
  12       *
  13       * Return a binary value as decimal.
  14       *
  15       * Excel Function:
  16       *        BIN2DEC(x)
  17       *
  18       * @param array|string $value The binary number (as a string) that you want to convert. The number
  19       *                                cannot contain more than 10 characters (10 bits). The most significant
  20       *                                bit of number is the sign bit. The remaining 9 bits are magnitude bits.
  21       *                                Negative numbers are represented using two's-complement notation.
  22       *                                If number is not a valid binary number, or if number contains more than
  23       *                                10 characters (10 bits), BIN2DEC returns the #NUM! error value.
  24       *                      Or can be an array of values
  25       *
  26       * @return array|string Result, or an error
  27       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  28       *            with the same dimensions
  29       */
  30      public static function toDecimal($value)
  31      {
  32          if (is_array($value)) {
  33              return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
  34          }
  35  
  36          try {
  37              $value = self::validateValue($value);
  38              $value = self::validateBinary($value);
  39          } catch (Exception $e) {
  40              return $e->getMessage();
  41          }
  42  
  43          if (strlen($value) == 10) {
  44              //    Two's Complement
  45              $value = substr($value, -9);
  46  
  47              return '-' . (512 - bindec($value));
  48          }
  49  
  50          return (string) bindec($value);
  51      }
  52  
  53      /**
  54       * toHex.
  55       *
  56       * Return a binary value as hex.
  57       *
  58       * Excel Function:
  59       *        BIN2HEX(x[,places])
  60       *
  61       * @param array|string $value The binary number (as a string) that you want to convert. The number
  62       *                                cannot contain more than 10 characters (10 bits). The most significant
  63       *                                bit of number is the sign bit. The remaining 9 bits are magnitude bits.
  64       *                                Negative numbers are represented using two's-complement notation.
  65       *                                If number is not a valid binary number, or if number contains more than
  66       *                                10 characters (10 bits), BIN2HEX returns the #NUM! error value.
  67       *                      Or can be an array of values
  68       * @param array|int $places The number of characters to use. If places is omitted, BIN2HEX uses the
  69       *                                minimum number of characters necessary. Places is useful for padding the
  70       *                                return value with leading 0s (zeros).
  71       *                                If places is not an integer, it is truncated.
  72       *                                If places is nonnumeric, BIN2HEX returns the #VALUE! error value.
  73       *                                If places is negative, BIN2HEX returns the #NUM! error value.
  74       *                      Or can be an array of values
  75       *
  76       * @return array|string Result, or an error
  77       *         If an array of numbers is passed as an argument, then the returned result will also be an array
  78       *            with the same dimensions
  79       */
  80      public static function toHex($value, $places = null)
  81      {
  82          if (is_array($value) || is_array($places)) {
  83              return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places);
  84          }
  85  
  86          try {
  87              $value = self::validateValue($value);
  88              $value = self::validateBinary($value);
  89              $places = self::validatePlaces($places);
  90          } catch (Exception $e) {
  91              return $e->getMessage();
  92          }
  93  
  94          if (strlen($value) == 10) {
  95              $high2 = substr($value, 0, 2);
  96              $low8 = substr($value, 2);
  97              $xarr = ['00' => '00000000', '01' => '00000001', '10' => 'FFFFFFFE', '11' => 'FFFFFFFF'];
  98  
  99              return $xarr[$high2] . strtoupper(substr('0' . dechex((int) bindec($low8)), -2));
 100          }
 101          $hexVal = (string) strtoupper(dechex((int) bindec($value)));
 102  
 103          return self::nbrConversionFormat($hexVal, $places);
 104      }
 105  
 106      /**
 107       * toOctal.
 108       *
 109       * Return a binary value as octal.
 110       *
 111       * Excel Function:
 112       *        BIN2OCT(x[,places])
 113       *
 114       * @param array|string $value The binary number (as a string) that you want to convert. The number
 115       *                                cannot contain more than 10 characters (10 bits). The most significant
 116       *                                bit of number is the sign bit. The remaining 9 bits are magnitude bits.
 117       *                                Negative numbers are represented using two's-complement notation.
 118       *                                If number is not a valid binary number, or if number contains more than
 119       *                                10 characters (10 bits), BIN2OCT returns the #NUM! error value.
 120       *                      Or can be an array of values
 121       * @param array|int $places The number of characters to use. If places is omitted, BIN2OCT uses the
 122       *                                minimum number of characters necessary. Places is useful for padding the
 123       *                                return value with leading 0s (zeros).
 124       *                                If places is not an integer, it is truncated.
 125       *                                If places is nonnumeric, BIN2OCT returns the #VALUE! error value.
 126       *                                If places is negative, BIN2OCT returns the #NUM! error value.
 127       *                      Or can be an array of values
 128       *
 129       * @return array|string Result, or an error
 130       *         If an array of numbers is passed as an argument, then the returned result will also be an array
 131       *            with the same dimensions
 132       */
 133      public static function toOctal($value, $places = null)
 134      {
 135          if (is_array($value) || is_array($places)) {
 136              return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places);
 137          }
 138  
 139          try {
 140              $value = self::validateValue($value);
 141              $value = self::validateBinary($value);
 142              $places = self::validatePlaces($places);
 143          } catch (Exception $e) {
 144              return $e->getMessage();
 145          }
 146  
 147          if (strlen($value) == 10 && substr($value, 0, 1) === '1') { //    Two's Complement
 148              return str_repeat('7', 6) . strtoupper(decoct((int) bindec("11$value")));
 149          }
 150          $octVal = (string) decoct((int) bindec($value));
 151  
 152          return self::nbrConversionFormat($octVal, $places);
 153      }
 154  
 155      protected static function validateBinary(string $value): string
 156      {
 157          if ((strlen($value) > preg_match_all('/[01]/', $value)) || (strlen($value) > 10)) {
 158              throw new Exception(ExcelError::NAN());
 159          }
 160  
 161          return $value;
 162      }
 163  }