자바스크립트에서 소수의 덧셈, 뺄셈, 곱셈, 나눗셈을 할 때 소수점 이하 자릿수가 여러 개인 문제에 대해 제가 직접 연구하고 관련 테스트를 진행하여 도움이 필요한 친구들이 참고할 수 있도록 많은 지식을 얻었습니다.
흥미로운 테스트를 하나 알려드리겠습니다.
0.1 0.2 == 0.3 //false
갑자기 우울해졌습니다. 알겠습니다! 0.1 0.2는 다음과 같이 됩니다: 0.30000000000000004
또 다른 2.4/0.8 => 2.9999999999999996 이를 변경하고 정수(2.4 * 100)/(0.8 * 100)
10.22로 변환할 방법이 없습니다. 이제 우리는 0.11을 빼야 결과가 나옵니다 10.110000000000001이라는 값에 소수가 많이 들어 있었는데, toFixed 메소드를 사용해서 소수를 필터링했는데, 이전 변환 방법보다 어느 것이 더 효율적인지는 모르겠습니다. 정수로 변환한 다음 실행해 보세요. 다시 시도해 봅시다!
var date1 = new Date(); for(var i = 0; i < 10000; i++){ var result1 = (10.22 - 0.11).toFixed(2); } alert(new Date() - date1);//效率低 var date2 = new Date(); for(var j = 0; j < 10000; j++){ var result2 = (10.22 * 1000 - 0.11 * 1000) / 1000; } alert(new Date() - date2);//效率高 alert(0.1 + 0.2 == 0.3); //既然返回false alert(0.1 + 0.2); //既然返回0.30000000000000004 alert(parseFloat(0.1) + parseFloat(0.2)); //还是返回0.30000000000000004
몇 가지 정보를 확인해 보니 하나는 자바스크립트 부동 소수점 계산의 버그이고, 다른 하나는 최종적으로 컴퓨터를 이진 계산으로 변환하는 것과 관련이 있지만, 왜 모든 소수가 그렇지 않은가? 이 현상은 항상 일어날 것이다. 아직은 시간이 나면 자세히 연구해 보도록 하겠다.
해결 방법:
이 문제를 해결하는 방법에는 두 가지가 있습니다. 첫 번째는 JavaScript의 toFixed(n) 메서드를 사용하여 소수점 N 자리를 직접 얻는 것입니다. 그러나 개인적으로 이 방법은 데이터 정확성에 문제가 있다고 생각합니다. 데이터 정확도 요구 사항이 높지 않은 경우 사용할 수 있습니다.
alert((0.1 + 0.2).toFixed(1));
두 번째 방법은 계산 방법을 직접 작성하는 것입니다. 다음은 사용자 정의 추가 기능입니다. 이 방법을 사용하면 위의 문제를 피할 수 있습니다.
//自定义加法运算 function addNum (num1, num2) { var sq1,sq2,m; try { sq1 = num1.toString().split(".")[1].length; } catch (e) { sq1 = 0; } try { sq2 = num2.toString().split(".")[1].length; } catch (e) { sq2 = 0; } m = Math.pow(10,Math.max(sq1, sq2)); return (num1 * m + num2 * m) / m; } alert(addNum(0.1, 0.2));
물론 다음과 같이 간단하게 작성할 수도 있습니다. 이런 식으로 N 다중 소수점은 다음과 같습니다. 장소는 나타나지 않습니다.
alert((num * 3 10 * 3) /3); 및 경고(num 10); 컴퓨터가 하위 수준에서 이진 연산으로 변환할 때 이 두 가지 쓰기 방법에는 차이가 있습니다. 위 문제의 원인, 또는 우리가 그것에 대해 깊이 연구해야 하고 더 많이 논의할 수 있습니다.
위 내용은 이 장의 전체 내용입니다. 더 많은 관련 튜토리얼을 보려면 JavaScript 비디오 튜토리얼을 방문하세요.