Se eu te perguntar quanto é 0,1 + 0,2? Você pode me dar uma olhada vazia, 0,1 + 0,2 = 0,3 Ah, você ainda precisa perguntar? Até as crianças do jardim de infância podem responder a essa pergunta pediátrica. Mas você sabe, o mesmo problema em uma linguagem de programação pode não ser tão simples quanto se imagina.
Não acredite? Vejamos primeiro um pedaço de JS.
var numA = 0,1;
var numB = 0,2;
alerta ((numA + numB) === 0,3);
O resultado da execução é falso. Sim, quando vi esse código pela primeira vez, presumi que era verdade, mas os resultados da execução me surpreenderam. Meu método de abertura está errado? Não, não. Vamos tentar executar o código a seguir novamente e saberemos porque o resultado é falso.
var numA = 0,1;
var numB = 0,2;
alerta(numA + numB);
Acontece que 0,1 + 0,2 = 0,3000000000000004. Não é estranho? Na verdade, para as quatro operações aritméticas de números de ponto flutuante, quase todas as linguagens de programação terão problemas semelhantes aos erros de precisão. No entanto, em linguagens como C++/C#/Java, os métodos foram encapsulados para evitar problemas de precisão. e JavaScript é um tipo fraco. A linguagem não possui um tipo de dados estrito para números de ponto flutuante do ponto de vista do design, portanto, o problema do erro de precisão é particularmente proeminente. Vamos analisar por que existe esse erro de precisão e como corrigi-lo.
Em primeiro lugar, temos que pensar no problema aparentemente pediátrico de 0,1 + 0,2 do ponto de vista do computador. Sabemos que o que pode ser lido pelos computadores é binário, não decimal, então vamos primeiro converter 0,1 e 0,2 em binário e dar uma olhada:
0,1 => 0,0001 1001 1001 1001… (loop infinito)
0,2 => 0,0011 0011 0011 0011… (loop infinito)
A parte decimal de um número de ponto flutuante de precisão dupla suporta até 52 bits, portanto, após adicionar os dois, obtemos uma string de 0,0100110011001100110011001100110011001100110011001100 O número binário é truncado devido à limitação de casas decimais dos números de ponto flutuante. Neste momento, convertemos para decimal e ele se torna 0,3000000000000004.
Então é isso, então como resolver esse problema? O resultado que quero é 0,1 + 0,2 === 0,3 Ah! ! !
Uma das soluções mais simples é fornecer requisitos de precisão claros. Durante o processo de retorno do valor, o computador irá arredondar automaticamente, como:
var numA = 0,1;
var numB = 0,2;
alerta(parseFloat((numA + numB).toFixed(2)) === 0,3 );
Mas obviamente este não é um método definitivo. Seria ótimo se houvesse um método que pudesse nos ajudar a resolver o problema de precisão desses números de ponto flutuante. Vamos tentar este método:
Math.formatFloat = função(f, dígito) {
var m = Math.pow(10, dígito);
return parseInt(f * m, 10) /m;
}
var numA = 0,1;
var numB = 0,2;
alerta(Math.formatFloat(numA + numB, 1) === 0,3);
O que esse método significa? Para evitar diferenças de precisão, precisamos multiplicar o número a ser calculado por 10 elevado à enésima potência, convertê-lo em um número inteiro que o computador possa reconhecer com precisão e, em seguida, dividi-lo por 10 elevado à enésima potência. linguagens de programação lidam com diferenças de precisão, usaremos isso para lidar com o erro de precisão de números de ponto flutuante em JS.
Se alguém lhe perguntar na próxima vez quanto é igual a 0,1 + 0,2, você deve ter cuidado com sua resposta! !