Última versión: 1.0.0-beta
Biblioteca PHP 5.3+ para operaciones aritméticas con números enteros que se ajusta al desbordamiento.
Atención
Esta biblioteca no está diseñada para usarse como una forma de realizar correctamente operaciones aritméticas con números enteros y no debe usarse en lugar de los operadores aritméticos nativos ni de cualquier otra biblioteca diseñada para tal fin.
A diferencia de otros lenguajes que desbordan números enteros positivos grandes en números enteros negativos grandes, PHP en realidad desborda números enteros en números de punto flotante. En la mayoría de los casos, los desbordamientos aritméticos deben tratarse como una circunstancia inusual que requiere un manejo especial. Sin embargo, hay algunos casos en los que este comportamiento envolvente es realmente útil, por ejemplo con números de secuencia TCP o ciertos algoritmos, como el cálculo hash. Esta clase de utilidad proporciona funciones aritméticas básicas que operan de acuerdo con ese comportamiento.
Para ilustrar, considere el siguiente ejemplo:
// 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 ));
Como se mostró anteriormente, sumar uno al entero más grande admitido mediante operadores aritméticos nativos dará como resultado un número de punto flotante. Por el contrario, usar IntMath::add() provocará un desbordamiento, lo que dará como resultado el entero más pequeño admitido en esta compilación de PHP.
La API está ampliamente documentada en el código fuente. Además, también está disponible una versión HTML para una visualización más cómoda en el navegador.
Utilice Composer para instalar el paquete:
$ composer require phpcommon/intmath
Actualmente, sólo se admiten las cuatro operaciones aritméticas básicas (suma, resta, multiplicación y división) y la negación.
Para valores enteros, la negación es lo mismo que la resta de cero. Debido a que PHP usa representación en complemento a dos para números enteros y el rango de valores en complemento a dos no es simétrico, la negación del entero negativo máximo da como resultado el mismo número negativo máximo. A pesar de que se ha producido un desbordamiento, no se produce ninguna excepción.
Para todos los valores enteros $a
, -$a
es igual a (~$a) + 1
.
Uso de ejemplo de API:
// Outputs int(-100)
var_dump (IntMath:: negate ( 100 ));
El resultado de sumar dos números enteros son los bits de orden inferior del verdadero resultado matemático representado en un formato de complemento a dos suficientemente amplio. Si se produce un desbordamiento, entonces el signo del resultado puede no ser el mismo que el signo de la suma matemática de los dos valores. A pesar del desbordamiento, en este caso no se produce ninguna excepción.
Uso de ejemplo de API:
// Outputs int(300)
var_dump (IntMath:: add ( 100 , 200 ));
La resta de un número positivo produce el mismo resultado que la suma de un número negativo de igual magnitud. Además, la resta de cero es lo mismo que la negación. El resultado son los bits de orden inferior del verdadero resultado matemático representados en un formato de complemento a dos suficientemente amplio. Si se produce un desbordamiento, entonces el signo del resultado puede no ser el mismo que el signo de la diferencia matemática de los dos valores. A pesar del desbordamiento, en este caso no se produce ninguna excepción.
Uso de ejemplo de API:
// Outputs int(90)
IntMath:: subtract ( 100 , 10 );
El resultado de multiplicar dos números enteros son los bits de bajo orden del verdadero resultado matemático representados en un formato de complemento a dos suficientemente amplio. Si se produce un desbordamiento, entonces el signo del resultado puede no ser el mismo que el signo del producto matemático de los dos valores. A pesar del desbordamiento, en este caso no se produce ninguna excepción.
Uso de ejemplo de API:
// Outputs int(200)
IntMath:: multiply ( 100 , 2 );
La división redondea el resultado hacia cero. Por tanto, el valor absoluto del resultado es el mayor entero posible que sea menor o igual al valor absoluto del cociente de los dos operandos. El resultado es cero o positivo cuando los dos operandos tienen el mismo signo y cero o negativo cuando los dos operandos tienen signos opuestos.
Hay un caso especial que no cumple esta regla: si el dividendo es el entero negativo de mayor magnitud posible para su tipo y el divisor es -1
, entonces se produce un desbordamiento de enteros y el resultado es igual al dividendo. A pesar del desbordamiento, en este caso no se produce ninguna excepción. Por otro lado, si el valor del divisor en una división entera es 0
, entonces se lanza una DivisionByZeroException
.
Uso de ejemplo de API:
// Outputs int(50)
IntMath:: divide ( 100 , 2 );
Consulte CHANGELOG para obtener más información sobre los cambios recientes.
$ composer test
Consulte la documentación de prueba para obtener más detalles.
¡Las contribuciones al paquete siempre son bienvenidas!
Consulte CONTRIBUCIÓN y CONDUCTA para obtener más detalles.
Si descubre algún problema relacionado con la seguridad, envíe un correo electrónico a [email protected] en lugar de utilizar el rastreador de problemas.
Todo el contenido de este paquete tiene la licencia MIT.