JavaScript에서 긴 숫자를 빼기
-
20-09-2019 - |
문제
다음 스크립트에서 Q == 0 인 이유는 무엇입니까?
<script>
var start = 1234567890123456789;
var end = 1234567890123456799;
var q = end - start;
alert(q);
</script>
결과는 10이어야한다고 생각합니다.이 두 숫자를 빼는 올바른 방법은 무엇입니까?
해결책
JavaScript의 숫자는 플로팅 포인트이기 때문입니다. 그들은 정밀도가 제한되어 있습니다.
JavaScript가 매우 긴 숫자를 볼 때 64 비트 플로트로 표시 할 수있는 가장 가까운 숫자로 반올림합니다. 스크립트에서 start
그리고 end
같은 값으로 반올림하십시오.
alert(1234567890123456789); // says: 1234567890123456800
alert(1234567890123456799); // says: 1234567890123456800
큰 정수에서 정확한 산술을 수행하는 내장 방법은 없지만 다음과 같은 BigInteger 라이브러리를 사용할 수 있습니다. 이 하나.
다른 팁
Jason은 이미 그 이유를 게시했습니다. 솔루션의 경우 JavaScript Bigint 라이브러리를 얻을 수 있습니다. http://www-cs-students.stanford.edu/~tjw/jsbn/
const subtract = (a, b) => [a, b].map(n => [...n].reverse()).reduce((a, b) => a.reduce((r, d, i) => {
let s = d - (b[i] || 0)
if (s < 0) {
s += 10
a[i + 1]--
}
return '' + s + r
}, '').replace(/^0+/, ''))
모든 다른 테스트 사례를 처리하기 위해 이러한 것들에 대해 Big-Integer 라이브러리를 더 잘 사용하십시오.
이것은 당신이 사용할 수있는 일반적인 경우입니다 ....
그것은 설명합니다 자바 스크립트 문서:
ECMAScript 표준에 따르면 숫자 유형은 단 하나뿐입니다. 이중-프레임 64 비트 바이너리 형식 IEEE 754 값 (사이의 숫자
-(2
53
-1)
그리고2
53
-1
). 정수에 대한 특정 유형은 없습니다.
Wikipedia 페이지에 대한 페이지 이중 정밀 플로팅 포인트 형식 설명 :
사이
2
52
= 4,503,599,627,370,496
그리고2
53
= 9,007,199,254,740,992
대표 숫자는 정수입니다. 다음 범위에서2
53
에게2
54
, 모든 것이 곱합니다2
, 대표적인 숫자는 짝수 숫자 등입니다.
(모든 정수 번호보다 작습니다 2
52
정확히 표현됩니다.)
1234567890123456789
그리고 1234567890123456799
보다 큽니다 2
60
= 1152921504606846976
. 이 크기에서는 정수 수의 약 1%만이 이중 정제 플로팅 포인트 형식을 사용하여 정확히 저장됩니다.
이 두 가지는 정확히 저장할 수 없습니다. 그들은 둘 다 둥글다 1234567890123456800
.
그만큼 자바 스크립트 문서 또한 정수 번호가 정확히 저장되는지 알리는 방법을 설명합니다.
...] 그리고 ECMAScript 6부터 시작하여 숫자가 이중 정제 플로팅 포인트 숫자 범위에 있는지 확인할 수도 있습니다.
Number.isSafeInteger()
만큼 잘Number.MAX_SAFE_INTEGER
그리고Number.MIN_SAFE_INTEGER
. 이 범위를 넘어서, JavaScript의 정수는 더 이상 안전하지 않으며 값의 이중 정제 부동 소수점 근사치가됩니다.