# tablepress/3.4/libraries/vendor/PhpSpreadsheet/Calculation/Engineering/BitWise.php

TablePress – Tables in WordPress made easy, version 3.4. 253 lines.

- Page: https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/Engineering/BitWise.php
- Raw: https://pluginprobe.com/plugins/tablepress/3.4/raw/libraries/vendor/PhpSpreadsheet/Calculation/Engineering/BitWise.php
- Modified: 2025-08-26T04:06:14+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/Engineering/BitWise.php#L10-L20`.

```php
<?php

namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\Engineering;

use TablePress\PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Exception;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;

class BitWise
{
	use ArrayEnabled;

	const SPLIT_DIVISOR = 2 ** 24;

	/**
				 * Split a number into upper and lower portions for full 32-bit support.
				 *
				 * @return int[]
				 * @param float|int $number
				 */
				private static function splitNumber($number): array
	{
		return [(int) floor($number / self::SPLIT_DIVISOR), (int) fmod($number, self::SPLIT_DIVISOR)];
	}

	/**
	 * BITAND.
	 *
	 * Returns the bitwise AND of two integer values.
	 *
	 * Excel Function:
	 *        BITAND(number1, number2)
	 *
	 * @param null|array<mixed>|bool|float|int|string $number1 Or can be an array of values
	 * @param null|array<mixed>|bool|float|int|string $number2 Or can be an array of values
	 *
	 * @return array<mixed>|int|string If an array of numbers is passed as an argument, then the returned result will also be an array
	 *            with the same dimensions
	 */
	public static function BITAND($number1, $number2)
	{
		if (is_array($number1) || is_array($number2)) {
			return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2);
		}

		try {
			$number1 = self::validateBitwiseArgument($number1);
			$number2 = self::validateBitwiseArgument($number2);
		} catch (Exception $e) {
			return $e->getMessage();
		}
		$split1 = self::splitNumber($number1);
		$split2 = self::splitNumber($number2);

		return self::SPLIT_DIVISOR * ($split1[0] & $split2[0]) + ($split1[1] & $split2[1]);
	}

	/**
	 * BITOR.
	 *
	 * Returns the bitwise OR of two integer values.
	 *
	 * Excel Function:
	 *        BITOR(number1, number2)
	 *
	 * @param null|array<mixed>|bool|float|int|string $number1 Or can be an array of values
	 * @param null|array<mixed>|bool|float|int|string $number2 Or can be an array of values
	 *
	 * @return array<mixed>|int|string If an array of numbers is passed as an argument, then the returned result will also be an array
	 *            with the same dimensions
	 */
	public static function BITOR($number1, $number2)
	{
		if (is_array($number1) || is_array($number2)) {
			return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2);
		}

		try {
			$number1 = self::validateBitwiseArgument($number1);
			$number2 = self::validateBitwiseArgument($number2);
		} catch (Exception $e) {
			return $e->getMessage();
		}

		$split1 = self::splitNumber($number1);
		$split2 = self::splitNumber($number2);

		return self::SPLIT_DIVISOR * ($split1[0] | $split2[0]) + ($split1[1] | $split2[1]);
	}

	/**
	 * BITXOR.
	 *
	 * Returns the bitwise XOR of two integer values.
	 *
	 * Excel Function:
	 *        BITXOR(number1, number2)
	 *
	 * @param null|array<mixed>|bool|float|int|string $number1 Or can be an array of values
	 * @param null|array<mixed>|bool|float|int|string $number2 Or can be an array of values
	 *
	 * @return array<mixed>|int|string If an array of numbers is passed as an argument, then the returned result will also be an array
	 *            with the same dimensions
	 */
	public static function BITXOR($number1, $number2)
	{
		if (is_array($number1) || is_array($number2)) {
			return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2);
		}

		try {
			$number1 = self::validateBitwiseArgument($number1);
			$number2 = self::validateBitwiseArgument($number2);
		} catch (Exception $e) {
			return $e->getMessage();
		}

		$split1 = self::splitNumber($number1);
		$split2 = self::splitNumber($number2);

		return self::SPLIT_DIVISOR * ($split1[0] ^ $split2[0]) + ($split1[1] ^ $split2[1]);
	}

	/**
	 * BITLSHIFT.
	 *
	 * Returns the number value shifted left by shift_amount bits.
	 *
	 * Excel Function:
	 *        BITLSHIFT(number, shift_amount)
	 *
	 * @param null|array<mixed>|bool|float|int|string $number Or can be an array of values
	 * @param null|array<mixed>|bool|float|int|string $shiftAmount Or can be an array of values
	 *
	 * @return array<mixed>|float|string If an array of numbers is passed as an argument, then the returned result will also be an array
	 *            with the same dimensions
	 */
	public static function BITLSHIFT($number, $shiftAmount)
	{
		if (is_array($number) || is_array($shiftAmount)) {
			return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount);
		}

		try {
			$number = self::validateBitwiseArgument($number);
			$shiftAmount = self::validateShiftAmount($shiftAmount);
		} catch (Exception $e) {
			return $e->getMessage();
		}

		$result = floor($number * (2 ** $shiftAmount));
		if ($result > 2 ** 48 - 1) {
			return ExcelError::NAN();
		}

		return $result;
	}

	/**
	 * BITRSHIFT.
	 *
	 * Returns the number value shifted right by shift_amount bits.
	 *
	 * Excel Function:
	 *        BITRSHIFT(number, shift_amount)
	 *
	 * @param null|array<mixed>|bool|float|int|string $number Or can be an array of values
	 * @param null|array<mixed>|bool|float|int|string $shiftAmount Or can be an array of values
	 *
	 * @return array<mixed>|float|string If an array of numbers is passed as an argument, then the returned result will also be an array
	 *            with the same dimensions
	 */
	public static function BITRSHIFT($number, $shiftAmount)
	{
		if (is_array($number) || is_array($shiftAmount)) {
			return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount);
		}

		try {
			$number = self::validateBitwiseArgument($number);
			$shiftAmount = self::validateShiftAmount($shiftAmount);
		} catch (Exception $e) {
			return $e->getMessage();
		}

		$result = floor($number / (2 ** $shiftAmount));
		if ($result > 2 ** 48 - 1) { // possible because shiftAmount can be negative
			return ExcelError::NAN();
		}

		return $result;
	}

	/**
				 * Validate arguments passed to the bitwise functions.
				 * @param mixed $value
				 */
				private static function validateBitwiseArgument($value): float
	{
		$value = self::nullFalseTrueToNumber($value);

		if (is_numeric($value)) {
			$value = (float) $value;
			if ($value == floor($value)) {
				if (($value > 2 ** 48 - 1) || ($value < 0)) {
					throw new Exception(ExcelError::NAN());
				}

				return floor($value);
			}

			throw new Exception(ExcelError::NAN());
		}

		throw new Exception(ExcelError::VALUE());
	}

	/**
				 * Validate arguments passed to the bitwise functions.
				 * @param mixed $value
				 */
				private static function validateShiftAmount($value): int
	{
		$value = self::nullFalseTrueToNumber($value);

		if (is_numeric($value)) {
			if (abs($value + 0) > 53) {
				throw new Exception(ExcelError::NAN());
			}

			return (int) $value;
		}

		throw new Exception(ExcelError::VALUE());
	}

	/**
				 * Many functions accept null/false/true argument treated as 0/0/1.
				 * @param mixed $number
				 * @return mixed
				 */
				private static function nullFalseTrueToNumber(&$number)
	{
		if ($number === null) {
			$number = 0;
		} elseif (is_bool($number)) {
			$number = (int) $number;
		}

		return $number;
	}
}

```
