js의 자릿수가 너무 커서 매개변수 정밀도가 손실되는 예를 공유해 주세요
최근에 매개변수를 전달할 때 이상한 문제가 발생했습니다. js 함수에 비트가 전달되는 경우 숫자가 상대적으로 큽니다. 인수를 인쇄해 보면 전달된 매개변수가 변경된 것을 확인할 수 있습니다.
그러다가 확인해보니 정말 js 정확도가 떨어져서 발생한 현상이었습니다. 내 해결책은 숫자 유형을 문자 유형 전송으로 변경하여 정확도가 손실되지 않도록 하는 것입니다. 아래와 같습니다.
컴퓨터의 바이너리 구현과 자릿수 제한 . 일부 숫자는 유한하게 표현될 수 없습니다. 파이 3.1415926..., 1.3333... 등과 같은 일부 무리수를 유한하게 표현할 수 없는 것과 같습니다. JS는 IEEE를 준수합니다. 754 사양은 배정밀도 저장소(이중 정밀도)를 사용하며 64비트를 차지합니다. 그림과 같이
의미
1비트를 사용하여 부호비트를 표현합니다.
11비트는 지수를 나타내는 데 사용됩니다.
52비트는 가수를 나타냅니다.
과 같은 부동 소수점 숫자
0.1 >> 0.0001 1001 1001 1001…(1001无限循环) 0.2 >> 0.0011 0011 0011 0011…(0011无限循环)
이때는 십진수만 흉내낼 수 있습니다. 반올림을 하는데 이진수는 0과 1 두 개뿐이므로 0이 되어 1로 반올림됩니다. 이는 컴퓨터의 일부 부동 소수점 연산에서 오류 및 정밀도 손실의 근본 원인입니다.
큰 정수의 정밀도 손실은 부동소수점 숫자의 정밀도 손실과 본질적으로 동일합니다. 최대 가수 자릿수는 52이므로 JS에서 정확하게 표현할 수 있는 가장 큰 정수는 Math.pow(2, 53) 십진수로는 9007199254740992이다.
9007199254740992보다 크면 정확도가 떨어질 수 있음
9007199254740992 >> 10000000000000...000 // 共计 53 个 0 9007199254740992 + 1 >> 10000000000000...001 // 中间 52 个 0 9007199254740992 + 2 >> 10000000000000...010 // 中间 51 个 0
실제로
9007199254740992 + 1 // 丢失 9007199254740992 + 2 // 未丢失 9007199254740992 + 3 // 丢失 9007199254740992 + 4 // 未丢失
결과는 그림과 같습니다
위의 내용은 괜찮습니다. 컴퓨터의 이진수 표현에서는 유한해 보이는 숫자가 실제로 무한하다는 것을 알고 있습니다. 저장 자릿수 제한으로 인해 "반올림"이 발생하고 정밀도가 손실됩니다.
想了解更深入的分析可以看这篇论文(又长又臭):What Every Computer Scientist Should Know About Floating-Point Arithmetic
对于整数,前端出现问题的几率可能比较低,毕竟很少有业务需要需要用到超大整数,只要运算结果不超过 Math.pow(2, 53) 就不会丢失精度。
对于小数,前端出现问题的几率还是很多的,尤其在一些电商网站涉及到金额等数据。解决方式:把小数放到位整数(乘倍数),再缩小回原来倍数(除倍数
// 0.1 + 0.2 (0.1*10 + 0.2*10) / 10 == 0.3 // true
위 내용은 js의 숫자가 너무 많아 매개변수 정밀도가 손실되는 예를 공유하세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!