Integer Utilities
Utilities for emulating WebAssembly 32-bit and 64-bit integer operations in PHP. These may be useful for porting an
application or library from C, C++, or other languages.
Requirements
This package requires a 64-bit build of PHP 8.4 or later.
There is no dependency on external Composer packages or PHP extensions.
Installation
Install via Composer.
composer require adept-digital/int-utils
Usage
There are two classes with near-identical interfaces:
\AdeptDigital\IntUtils\Int32
\AdeptDigital\IntUtils\Int64
The following operations are provided:
add(int $a, int $b): int: Integer addition.
sub(int $a, int $b): int: Integer subtraction.
mul(int $a, int $b): int: Integer multiplication.
div_s(int $a, int $b): int: Signed integer division. 1
div_u(int $a, int $b): int: Unsigned integer division.
rem_s(int $a, int $b): int: Signed integer modulo. 1
rem_u(int $a, int $b): int: Unsigned integer modulo.
eq(int $a, int $b): int: Equal comparison. 2
eqz(int $a): int: Equals zero test. 2
ne(int $a, int $b): int: Not equal comparison. 2
lt_s(int $a, int $b): int: Signed less than comparison. 2
lt_u(int $a, int $b): int: Unsigned less than comparison.
le_s(int $a, int $b): int: Signed less than or equal comparison. 2
le_u(int $a, int $b): int: Unsigned less than or equal comparison.
gt_s(int $a, int $b): int: Signed greater than comparison. 2
gt_u(int $a, int $b): int: Unsigned greater than comparison.
ge_s(int $a, int $b): int: Signed greater than or equal comparison. 2
ge_u(int $a, int $b): int: Unsigned greater than or equal comparison.
and(int $a, int $b): int: Bitwise AND. 1
or(int $a, int $b): int: Bitwise OR. 1
xor(int $a, int $b): int: Bitwise XOR. 1
shl(int $a, int $b): int: Shift left. 2
shr_s(int $a, int $b): int: Signed (arithmetic) shift right. 2
shr_u(int $a, int $b): int: Unsigned (logical) shift right.
rotl(int $a, int $b): int: Rotate left.
rotr(int $a, int $b): int: Rotate right.
clz(int $a): int: Count leading zeros.
ctz(int $a): int: Count trailing zeros.
popcnt(int $a): int: Population count.
extend8_s(int $a): int: Extend the sign of the least significant 8 bits.
extend16_s(int $a): int: Extend the sign of the least significant 16 bits.
extend32_s(int $a): int: Extend the sign of the least significant 32 bits. 3
32-bit representation
PHP has no 32-bit integer type, so 32-bit numbers are represented in 64-bit, but are limited to the range of a signed
32-bit integer (-2,147,483,648 to 2,147,483,647). For example, 4,294,967,295 (2**32-1) should be represented as
-1. Using numbers outside this range will cause a RangeException to be thrown, unless assertions are disabled, in
which case the result is undefined.
To correctly format an unsigned 32-bit integer, unset the most significant 32 bits:
use \AdeptDigital\IntUtils\Int32;
echo Int32::add(Int32::MAX, 1) & 0xFFFF_FFFF;
64-bit representation
PHP has no unsigned integer type, so numbers larger than PHP_INT_MAX will appear to be negative.
To correctly format an unsigned integer, use printf() or sprintf():
use \AdeptDigital\IntUtils\Int64;
printf('%u', Int64::add(Int64::MAX, 1));
Contributing
All contributions are welcome. If you would like to work on a new feature, consider creating an issue before starting.
TODO
- Add benchmarks and benchmark on different machines.
- Add alternative implementations (eg: GMP, FFI, custom extension).
- Add feature detection for alternative implementations.
License
Copyright 2025 David Gallagher david@adeptdigital.com.au.
The package is licensed under the GNU Lesser General Public License 3.0 or later.