"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Posso confiar na precisão `php.ini` do PHP para cálculos monetários precisos?

Posso confiar na precisão `php.ini` do PHP para cálculos monetários precisos?

Publicado em 19/11/2024
Navegar:570

 Can I Rely on PHP's `php.ini` Precision for Accurate Money Calculations?

Posso confiar na solução alternativa de precisão do PHP php.ini para problemas de ponto flutuante?

Introdução

A aritmética de ponto flutuante, um assunto complexo muitas vezes mal compreendido, permeia os sistemas de computador modernos. Como a maioria dos números fracionários não possui uma representação binária exata, o arredondamento ocorre inevitavelmente. Compreender as nuances das operações de ponto flutuante é crucial, conforme descrito em "O que todo cientista da computação deve saber sobre aritmética de ponto flutuante".

Perguntas e respostas


Pergunta 1: Posso usar a solução alternativa de precisão para cálculos precisos de 2 dígitos (por exemplo, dinheiro)?

Resposta: Não, você não pode confiar nas configurações de precisão do php.ini para precisão consistente de 2 dígitos, mesmo para números abaixo de 10 ^ 6, porque o comprimento da precisão pode aumentar durante os cálculos.

Pergunta 2: forneça um exemplo claro de onde a solução alternativa de precisão falha.

Resposta: Considere o seguinte exemplo com desconto de 10% aplicado apenas ao primeiro quilograma:

ini_set('precision', 8); // Your precision
$a = 5.88; // Cost of 1kg
$q = 2.49; // User buys 2.49 kg
$b = $a * 0.01; // 10% Discount only on the first kg
echo ($a * $q) - $b;

Saída: 14.5824

Pergunta 3: Qual php.ini O valor .precision é adequado para cálculos monetários de 2 dígitos?

Resposta: As configurações de precisão do PHP não são uma base confiável para cálculos financeiros ou precisão de ponto flutuante. É melhor usar bibliotecas ou métodos especializados.

Cálculos de exemplo

Vamos examinar vários exemplos para ilustrar as limitações de precisão:

$a = 342349.23;
$b = 341765.07;

// Example A: precision = 20
echo $a - $b, PHP_EOL; // 584.15999999997438863
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.15999999999996817 (rounding introduces instability)
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.15

// Example B: precision = 14
echo $a - $b, PHP_EOL; // 584.15999999997
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.16

// Example C: precision = 6
echo $a - $b, PHP_EOL; // 584.16
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.00

// Example D: precision = 3
echo $a - $b, PHP_EOL; // 584
echo floatval(round($a - $b, 2)), PHP_EOL; // 584
echo number_format($a - $b, 2), PHP_EOL; // 584.16 (consistent)
echo bcsub($a, $b, 2), PHP_EOL; // 0.00

Esses exemplos demonstram as inconsistências em confiar nas configurações de precisão do PHP para cálculos precisos.

Conclusão

Para cálculos financeiros confiáveis, esqueça sobre ponto flutuante e use centavos ou considere a função number_format para precisão consistente de 2 dígitos.

Update

ini_set('precision', 8);

$a = 0.19;
$b = 0.16;
$c = 0.01;
$d = 0.01;
$e = 0.01;
$f = 0.01;
$g = 0.01;
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3