Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Precisão decimal do MySQL e PHP errada


De um artigo que escrevi para Authorize.Net :

Um mais um é igual a dois, certo? Que tal 0,2 mais 1,4 vezes 10? Isso é igual a 16, certo? Não se você estiver fazendo as contas com PHP (ou a maioria das outras linguagens de programação):
echo floor((0.2 + 1.4) * 10); // Should be 16. But it's 15!

Isso se deve ao modo como os números de ponto flutuante são tratados internamente. Eles são representados com um número fixo de casas decimais e podem resultar em números que não somam exatamente como você espera. Internamente, nosso exemplo de 0,2 mais 1,4 vezes 10 calcula aproximadamente 15,9999999998 ou mais. Esse tipo de matemática é bom ao trabalhar com números que não precisam ser precisos como porcentagens. Mas quando se trabalha com dinheiro, a precisão é importante, pois um centavo ou um dólar faltando aqui ou ali se acumula rapidamente e ninguém gosta de ficar com o dinheiro faltando.

A solução matemática BC

Felizmente, o PHP oferece a extensão BC Math que é "para matemática de precisão arbitrária, o PHP oferece a Calculadora Binária que suporta números de qualquer tamanho e precisão, representados como strings." Em outras palavras, você pode fazer cálculos precisos com valores monetários usando essa extensão. A extensão BC Math contém função s que permitem que você execute as operações mais comuns com precisão, incluindo adição , subtração , multiplicação e divisão .

Um exemplo melhor

Aqui está o mesmo exemplo acima, mas usando a função bcadd() para fazer as contas para nós. São necessários três parâmetros. Os dois primeiros são os valores que desejamos adicionar e o terceiro é o número de casas decimais para as quais desejamos ser precisos. Já que estamos trabalhando com dinheiro, definiremos a precisão como duas casas decimais.
echo floor(bcadd('0.2', '1.4', 2) * 10); // It's 16 like we would expect it to be.