kartavik/php-intmath

一个在整数溢出时回绕的整数运算库。

1.0.0 2019-08-12 13:37 UTC

This package is auto-updated.

Last update: 2024-09-13 02:13:29 UTC


README

Build Status Code Coverage Scrutinizer Code Quality StyleCI Latest Stable Version

PHP 5.3+ 整数溢出时回绕的整数运算库。

注意

此库不打算用作正确执行整数运算的方式,不应替代原生算术运算符或任何其他为此目的设计的库。

与其他将大正整数溢出为负整数的其他语言不同,PHP 实际上是将整数溢出为浮点数。在大多数情况下,整数溢出必须被视为一种特殊情况,需要特殊处理。然而,在某些情况下,这种回绕行为实际上是有用的 - 例如 TCP 序列号或某些算法,如哈希计算。此实用程序类提供符合该行为的基礎算術函數。

例如,考虑以下示例

// Output on 64-bit system: float(9.2233720368548E+18)
var_dump(PHP_MAX_INT + 1);

// Output on 64-bit system: int(-9223372036854775808)
var_dump(IntMath::add(PHP_MAX_INT, 1));

如前所述,将原生算術運算符支持的最大整數加一將會得到一個浮點數。相比之下,使用 IntMath::add() 會導致溢出,結果是此 PHP 版本支持的最小整數。

API 在源代码中进行了广泛文档记录。此外,还有一个 HTML 版本,便于在浏览器中查看。

安装

使用 Composer 安装此包

$ composer require kartavik/php-intmath

运算

目前,仅支持四种基本算術運算(加法、減法、乘法和除法)和取反。

取反

对于整数值,取反等同于从零减去该值。因为 PHP 使用二进制补码表示整数值,而二进制补码值的范围不对称,所以最大负整数的取反结果仍然是该最大负数。尽管发生了溢出,但没有抛出异常。

对于所有整数值 $a-$a 等于 (~$a) + 1

API 示例用法

// Outputs int(-100)
var_dump(IntMath::negate(100));

加法

两个整数相加的结果是真实数学结果在足够宽的二进制补码格式中的最低位。如果发生溢出,则结果的正负可能与两个值的数学和的正负不同。尽管发生了溢出,但在此情况下不会抛出异常。

API 示例用法

// Outputs int(300)
var_dump(IntMath::add(100, 200));

减法

减去一个正数的结果与加一个相等绝对值的负数的结果相同。此外,从零减去的结果与取反相同。结果是真实数学结果在足够宽的二进制补码格式中的最低位。如果发生溢出,则结果的正负可能与两个值的数学差的正负不同。尽管发生了溢出,但在此情况下不会抛出异常。

API 示例用法

// Outputs int(90)
IntMath::subtract(100, 10);

乘法

两个整数相乘的结果是真实数学结果在足够宽的二进制补码格式中的最低位。如果发生溢出,则结果的正负可能与两个值的数学积的正负不同。尽管发生了溢出,但在此情况下不会抛出异常。

API 示例用法

// Outputs int(200)
IntMath::multiply(100, 2);

除法

除法运算结果四舍五入到0。因此,结果绝对值是小于或等于两个操作数商的绝对值可能的最大整数。当两个操作数符号相同时,结果为零或正数;当两个操作数符号相反时,结果为零或负数。

有一种特殊情况不满足此规则:如果被除数是其类型可能的最大整数值的负数,且除数为-1,则发生整数溢出,结果等于被除数。尽管发生溢出,此情况下不会抛出异常。另一方面,如果整除操作中的除数值为0,则会抛出DivisionByZeroException异常。

API 示例用法

// Outputs int(50)
IntMath::divide(100, 2);

变更日志

有关最近更改的更多信息,请参阅CHANGELOG

测试

$ composer test

有关更多详细信息,请查看测试文档

贡献

我们始终欢迎对包的贡献!

请参阅CONTRIBUTINGCONDUCT以获取详细信息。

安全性

如果您发现任何与安全相关的问题,请通过电子邮件marcos@marcospassos.com联系,而不是使用问题跟踪器。

鸣谢

许可协议

本包所有内容均根据MIT许可协议授权。