Versão mais recente: 1.0.0-beta
Biblioteca PHP 5.3+ para operações aritméticas em números inteiros que giram em caso de estouro.
Atenção
Esta biblioteca não se destina a ser usada como uma forma de realizar operações aritméticas adequadamente em números inteiros e não deve ser usada no lugar dos operadores aritméticos nativos ou de qualquer outra biblioteca projetada para tal propósito.
Ao contrário de outras linguagens que fazem overflow de números inteiros positivos grandes em números inteiros negativos grandes, o PHP na verdade faz overflow de números inteiros para números de ponto flutuante. Na maioria dos casos, os overflows aritméticos devem ser tratados como uma circunstância incomum que requer tratamento especial. No entanto, há alguns casos em que esse comportamento envolvente é realmente útil - por exemplo, com números de sequência TCP ou determinados algoritmos, como cálculo de hash. Esta classe de utilitário fornece funções aritméticas básicas que operam de acordo com esse comportamento.
Para ilustrar, considere o seguinte exemplo:
// 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 ));
Conforme mostrado anteriormente, adicionar um ao maior número inteiro suportado usando operadores aritméticos nativos resultará em um número de ponto flutuante. Por outro lado, usar IntMath::add() causará um overflow, resultando no menor número inteiro suportado nesta compilação do PHP.
A API está amplamente documentada no código-fonte. Além disso, uma versão HTML também está disponível para visualização mais conveniente no navegador.
Use o Composer para instalar o pacote:
$ composer require phpcommon/intmath
Atualmente, apenas as quatro operações aritméticas básicas (adição, subtração, multiplicação e divisão) e negação são suportadas.
Para valores inteiros, a negação é o mesmo que a subtração de zero. Como o PHP usa representação em complemento de dois para números inteiros e o intervalo de valores em complemento de dois não é simétrico, a negação do número inteiro negativo máximo resulta no mesmo número negativo máximo. Apesar do fato de ter ocorrido overflow, nenhuma exceção é lançada.
Para todos os valores inteiros $a
, -$a
é igual a (~$a) + 1
.
Exemplo de uso da API:
// Outputs int(-100)
var_dump (IntMath:: negate ( 100 ));
O resultado da adição de dois inteiros são os bits de ordem inferior do verdadeiro resultado matemático, representados em um formato de complemento de dois suficientemente amplo. Se ocorrer overflow, então o sinal do resultado pode não ser igual ao sinal da soma matemática dos dois valores. Apesar do estouro, nenhuma exceção é lançada neste caso.
Exemplo de uso da API:
// Outputs int(300)
var_dump (IntMath:: add ( 100 , 200 ));
A subtração de um número positivo produz o mesmo resultado que a adição de um número negativo de igual magnitude. Além disso, a subtração de zero é o mesmo que a negação. O resultado são os bits de ordem inferior do verdadeiro resultado matemático, representados em um formato de complemento de dois suficientemente amplo. Se ocorrer overflow, então o sinal do resultado pode não ser igual ao sinal da diferença matemática dos dois valores. Apesar do estouro, nenhuma exceção é lançada neste caso.
Exemplo de uso da API:
// Outputs int(90)
IntMath:: subtract ( 100 , 10 );
O resultado da multiplicação de dois inteiros são os bits de ordem inferior do verdadeiro resultado matemático, representados em um formato de complemento de dois suficientemente amplo. Se ocorrer overflow, então o sinal do resultado pode não ser igual ao sinal do produto matemático dos dois valores. Apesar do estouro, nenhuma exceção é lançada neste caso.
Exemplo de uso da API:
// Outputs int(200)
IntMath:: multiply ( 100 , 2 );
A divisão arredonda o resultado para zero. Assim, o valor absoluto do resultado é o maior número inteiro possível menor ou igual ao valor absoluto do quociente dos dois operandos. O resultado é zero ou positivo quando os dois operandos possuem o mesmo sinal e zero ou negativo quando os dois operandos possuem sinais opostos.
Há um caso especial que não satisfaz esta regra: se o dividendo for o número inteiro negativo de maior magnitude possível para seu tipo e o divisor for -1
, então ocorre um estouro de número inteiro e o resultado é igual ao dividendo. Apesar do estouro, nenhuma exceção é lançada neste caso. Por outro lado, se o valor do divisor em uma divisão inteira for 0
, então uma DivisionByZeroException
será lançada.
Exemplo de uso da API:
// Outputs int(50)
IntMath:: divide ( 100 , 2 );
Consulte CHANGELOG para obter mais informações sobre o que mudou recentemente.
$ composer test
Confira a documentação do teste para obter mais detalhes.
Contribuições para o pacote são sempre bem-vindas!
Consulte CONTRIBUIÇÃO e CONDUTA para obter detalhes.
Se você descobrir algum problema relacionado à segurança, envie um e-mail para [email protected] em vez de usar o rastreador de problemas.
Todo o conteúdo deste pacote está licenciado sob a licença MIT.