언어로 정의되어 있습니까? 정의 된 최대 값이 있습니까? 브라우저마다 다른가요?
1n << 10000n
의존성을 요구하지 않고 정밀도를 잃지 않고 실제로 한계에 가깝지 않은 정말 큰 정수입니다.
언어로 정의되어 있습니까? 정의 된 최대 값이 있습니까? 브라우저마다 다른가요?
1n << 10000n
의존성을 요구하지 않고 정밀도를 잃지 않고 실제로 한계에 가깝지 않은 정말 큰 정수입니다.
답변:
JavaScript에는 두 가지 숫자 유형이 있습니다 : Number
및 BigInt
.
가장 자주 사용되는 숫자 유형 Number
은 64 비트 부동 소수점 IEEE 754 숫자입니다.
이 유형의 가장 큰 정확한 적분 값은 Number.MAX_SAFE_INTEGER
입니다.
이것을 1 조 1 천 바이트는 페타 바이트 (또는 1 천 테라 바이트)입니다.
이 문맥에서 "안전"은 정수를 정확하게 표현하고 정확하게 비교하는 능력을 말합니다.
크기가 2 53 보다 크지 않은 모든 양수 및 음수 는
Number
유형으로 표시 할 수 있습니다 (실제로 정수 0에는 +0 및 -0의 두 가지 표현이 있음).
이보다 큰 정수를 안전하게 사용하려면 다음을 사용해야합니다. BigInt
상한이없는 합니다.
비트 연산자와 시프트 연산자는 32 비트 정수에서 작동하므로이 경우 최대 안전 정수는 2 31 -1 또는 2,147,483,647입니다.
const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2) // 4503599627370496
log(x >> 1) // 0
log(x | 1) // 1
숫자 9,007,199,254,740,992의 주제에 대한 기술 노트 :이 값의 정확한 IEEE-754 표현이 있으며 변수 에서이 값을 할당하고 읽을 수 있으므로 매우 신중하게 정수 도메인 이하의 정수 도메인에서 선택된 응용 프로그램의 경우 이 값을 최대 값으로 취급 할 수 있습니다.
일반적으로이 IEEE-754 값은 논리 값 9,007,199,254,740,992 또는 9,007,199,254,740,993을 인코딩하는지 모호하기 때문에 정확하지 않은 것으로 취급해야합니다.
4294967295 === Math.pow(2,32) - 1;
> = ES6 :
Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;
<= ES5
에서 참조 :
Number.MAX_VALUE;
Number.MIN_VALUE;
Number.MIN_VALUE
가장 작은 수 있습니다 긍정적 인 숫자입니다. 최소 값 (즉, 적은 무엇보다도) 아마 -Number.MAX_VALUE
.
Number.MIN_SAFE_INTEGER
하고Number.MAX_SAFE_INTEGER
2 53 == 9 007 199 254 740 992입니다. 이는 Number
s가 52 비트 가수에 부동 소수점으로 저장 되기 때문 입니다.
최소값은 -2 53입니다. 입니다.
이로 인해 재미있는 일이 벌어집니다
Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true
그리고 위험 할 수도 있습니다 :)
var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
// infinite loop
}
추가 읽기 : http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
i += 1000000000
JavaScript에는이라는 숫자가 Infinity
있습니다.
예 :
(Infinity>100)
=> true
// Also worth noting
Infinity - 1 == Infinity
=> true
Math.pow(2,1024) === Infinity
=> true
이 주제에 관한 몇 가지 질문에 충분할 수 있습니다.
min
최소값을 찾을 때 변수 를 초기화하기에 충분 합니다.
Infinity - 1 === Infinity
1 - Infinity === -Infinity
지미의 대답은 정확히 같은 연속 자바 스크립트 정수 스펙트럼을 나타낸다 -9007199254740992 에 9007199254740992 포함을 (9007199254740993 죄송합니다, 당신이 생각하는 당신이 9007199254740993하지만, 당신이 잘못!에있는 아래 또는 데모 jsfiddle을 ).
console.log(9007199254740993);
그러나이 프로그래밍 방식으로 ( 28.56 년 후에 끝날 것이라고 CoolAJ86이 그의 답변 에서 언급 한 것 이외의) 찾거나 증명하는 대답 은 없으므로 여기에 약간 더 효율적인 방법이 있습니다 (정확히 말하면 더 효율적입니다) 28.559999999968312에 대한 년에 의하여 :)하는 함께 테스트 바이올린 :
/**
* Checks if adding/subtracting one to/from a number yields the correct result.
*
* @param number The number to test
* @return true if you can add/subtract 1, false otherwise.
*/
var canAddSubtractOneFromNumber = function(number) {
var numMinusOne = number - 1;
var numPlusOne = number + 1;
return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}
//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher
//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
highestNumber *= 2;
}
//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
highestNumber = highestNumber - numToSubtract;
}
numToSubtract /= 2;
}
//And there was much rejoicing. Yay.
console.log('HighestNumber = ' + highestNumber);
x++
는 증분이 발생 하기 전에 x 값을 제공 하므로 불일치를 설명합니다. 식이 x의 최종 값과 같은 것으로 평가되도록하려면 식을로 변경해야합니다 ++x
.
var MAX_INT = 4294967295;
나는 영리하다고 생각하고 그 가치를 발견했습니다. x + 1 === x
더 실용적인 접근 방식으로 .
내 컴퓨터는 초당 천만 개 정도만 계산할 수 있으므로 28.56 년 후에 최종 답변을 게시하겠습니다.
그렇게 오래 기다릴 수 없다면 기꺼이 내기를하겠습니다
9007199254740992 === Math.pow(2, 53) + 1
충분히 증거입니다4294967295
하는 것입니다 Math.pow(2,32) - 1
비트 이동과 피할 예상 문제로찾기 x + 1 === x
:
(function () {
"use strict";
var x = 0
, start = new Date().valueOf()
;
while (x + 1 != x) {
if (!(x % 10000000)) {
console.log(x);
}
x += 1
}
console.log(x, new Date().valueOf() - start);
}());
짧은 대답은 "그것은 달려있다"입니다.
어디서나 비트 연산자를 사용하는 경우 (또는 배열의 길이를 참조하는 경우) 범위는 다음과 같습니다.
부호없는 : 0…(-1>>>0)
서명 : (-(-1>>>1)-1)…(-1>>>1)
비트 연산자와 배열의 최대 길이는 32 비트 정수로 제한됩니다.
비트 연산자를 사용하지 않거나 배열 길이를 사용하는 경우 :
서명 : (-Math.pow(2,53))…(+Math.pow(2,53))
이러한 제한은 일반적으로 IEEE 754 배정 밀도 부동 소수점 표현에 해당하는 "Number"유형의 내부 표현에 의해 부과됩니다. (일반 부호있는 정수와 달리 음의 한계의 크기는 실제로 음의 0을 포함하는 내부 표현의 특성으로 인해 양의 한계의 크기와 같습니다 .)
ECMAScript 6 :
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
MAX_SAFE_INTEGER
거꾸로 작업하여 모든 브라우저에서 계산하는 것이 신뢰할 수 있습니까? 대신 앞으로 나아가 야합니까? 즉, Number.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52)-1) + 1;
Math.pow(2, 53)-1
안전한 작업은? 가장 큰 안전 정수보다 하나 더 큽니다.
이전의 많은 답변에서 9 007 199 254740 991 을 확인한 결과 true
를 보여주었습니다.9007199254740992 === 9007199254740992 + 1
이 최대 안전 정수임 .
축적을 계속하면 어떻게 되나요?
input: 9007199254740992 + 1 output: 9007199254740992 // expected: 9007199254740993
input: 9007199254740992 + 2 output: 9007199254740994 // expected: 9007199254740994
input: 9007199254740992 + 3 output: 9007199254740996 // expected: 9007199254740995
input: 9007199254740992 + 4 output: 9007199254740996 // expected: 9007199254740996
9 007 199 254 740 992 보다 큰 숫자 중에서도 짝수 만 나타낼 수 있음을 알 수 있습니다 .
배정도 64 비트 이진 형식 이 어떻게 작동 하는지 설명하는 입구 입니다. 어떻게 9 007 199 254740 992를 보자이 이진 형식을 사용하여 어떻게 유지 (표시) .
간단한 버전을 사용하여 4503 599 627 370 496 :
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
화살표의 왼쪽에는 비트 값 1 과 인접한 기수 점이 있으며을 곱 2^52
하면 기수 점이 오른쪽으로 52 단계 이동하여 끝으로 이동합니다. 이제 바이너리로 4503599627370496을 얻습니다.
이제 모든 비트가 1로 설정 될 때까지이 값에 1을 누적하기 시작합니다. 이는 10의 9 007 199 254 740 991 과 같습니다 .
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
(+1)
1 . 0000 ---- 0001 * 2^52 => 1 0000 ---- 0001.
(+1)
1 . 0000 ---- 0010 * 2^52 => 1 0000 ---- 0010.
(+1)
.
.
.
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
이제 배정도 64 비트 이진 형식 에서는 분수에 대해 52 비트를 엄격하게 할당하기 때문에 1을 더 추가하기 위해 더 이상 비트를 사용할 수 없으므로 모든 비트를 다시 0으로 설정하는 것이 가능합니다. 지수 부분을 조작하십시오.
|--> This bit is implicit and persistent.
|
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
|-- 52 bits --| |-- 52 bits --|
(+1)
(radix point has no way to go)
1 . 0000 ---- 0000 * 2^52 * 2 => 1 0000 ---- 0000. * 2
|-- 52 bits --| |-- 52 bits --|
=> 1 . 0000 ---- 0000 * 2^53
|-- 52 bits --|
이제 우리는 얻을 9 007 199 254 740 992를 , 그리고보다 숫자보다, 어떤 형식이 잡을 수 것은 함께 분수의 2 배 , 그것은 이유가, 지금은 분수 부분 사실이 추가로 동일에있는 모든 1 추가를 의미 더블 -정밀도 64 비트 이진 형식 은 숫자가 9 007 199 254740 992 보다 큰 경우 홀수를 보유 할 수 없습니다 .
(consume 2^52 to move radix point to the end)
1 . 0000 ---- 0001 * 2^53 => 1 0000 ---- 0001. * 2
|-- 52 bits --| |-- 52 bits --|
따라서 숫자가 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984보다 커지면 분수의 4 배만 보유 할 수 있습니다.
input: 18014398509481984 + 1 output: 18014398509481984 // expected: 18014398509481985
input: 18014398509481984 + 2 output: 18014398509481984 // expected: 18014398509481986
input: 18014398509481984 + 3 output: 18014398509481984 // expected: 18014398509481987
input: 18014398509481984 + 4 output: 18014398509481988 // expected: 18014398509481988
[ 2251 799 813 685 248 , 4 503 599 627 370 496 사이의 숫자는 어떻습니까?
1 . 0000 ---- 0001 * 2^51 => 1 0000 ---- 000.1
|-- 52 bits --| |-- 52 bits --|
기수 포인트 뒤의 비트 값 1은 정확히 2 ^ -1입니다. (= 1 / 2, = 0.5) 따라서 4 503 599 627 370 496 (2 ^ 52) 보다 작은 숫자 의 경우 정수 의 1/2 배 를 나타내는 데 사용할 수있는 비트가 있습니다 .
input: 4503599627370495.5 output: 4503599627370495.5
input: 4503599627370495.75 output: 4503599627370495.5
2251 799813 685248 미만 (2 ^ 51)
input: 2251799813685246.75 output: 2251799813685246.8 // expected: 2251799813685246.75
input: 2251799813685246.25 output: 2251799813685246.2 // expected: 2251799813685246.25
input: 2251799813685246.5 output: 2251799813685246.5
// If the digits exceed 17, JavaScript round it to print it.
//, but the value is held correctly:
input: 2251799813685246.25.toString(2)
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
그리고 사용 가능한 지수 부분의 범위는 무엇입니까? 형식은 11 비트를 할당합니다. 위키의 전체 형식 : (자세한 내용은 여기를 참조하십시오)
따라서 지수 부분을 2 ^ 52로 만들려면 정확히 e = 1075로 설정해야합니다.
다른 사람들은 이미 일반적인 대답을 주었을 지 모르지만 빠른 결정 방법을 제시하는 것이 좋습니다.
for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);
Chrome 30에서 밀리 초 이내에 9007199254740992를 제공합니다.
2를 제곱하면 '1을 더한'1이 자신과 같은 것을 찾는 것입니다.
시험:
maxInt = -1 >>> 1
Firefox 3.6에서는 2 ^ 31-1입니다.
^
것을 의미 합니다 . 자바 스크립트 콘솔에서 ^
입니다 XOR 하지 제기 -에
101
2이고 2는 010
입니다. 이제 비트 XOR을 사용하면 5(101) ^ 2(010) = 7(111)
혼란Math.pow()
^
글을 쓰는 시점에서 JavaScript는 새로운 데이터 유형을 받고 있습니다 : BigInt
. EcmaScript 2020에 포함되는 것은 4 단계 의 TC39 제안 입니다. Chrome 67 이상, FireFox 68 이상, Opera 54 및 Node 10.4.0에서 사용할 수 있습니다. 그것은 사파리 (Safari) 등에서 진행되고있다. 그것은 "n"접미사를 갖는 숫자 리터럴을 소개하고 임의의 정밀도를 허용한다 :BigInt
var a = 123456789012345678901012345678901n;
물론 이러한 숫자가 (의도적으로) 숫자 데이터 형식으로 강제 변환되면 정밀도는 여전히 손실됩니다.
그리고 분명히, 유한 한 메모리와 필요한 메모리를 할당하고 그러한 많은 수에 대해 산술을 수행하는 데 드는 시간면에서 정밀한 한계가 항상있을 것입니다.
예를 들어, 십진수가 십진수 인 숫자 생성에는 완료 전에 현저한 지연이 발생합니다.
console.log(BigInt("1".padEnd(100000,"0")) + 1n)
...하지만 작동합니다.
공식 X- (X + 1) =-1로 간단한 테스트를 수행했으며 XI의 최대 값은 Safari, Opera 및 Firefox에서 작동 할 수 있습니다 (OS X에서 테스트 됨)는 9e15입니다. 테스트에 사용한 코드는 다음과 같습니다.
javascript: alert(9e15-(9e15+1));
9000000000000000
1 개의 중요한 수치가 있습니다. `9007199254740992`에는 15 개의 유효 숫자가 있습니다.
9000000000000000
그대로 1
-SF가 있습니다. 어디에 90*10^14
갖는 2 ( sigfigscalculator.appspot.com ) mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (바닥 부)
MAX_SAFE_INTEGER
상수의 값을 갖는다9007199254740991
(또는 ~ 9,007,199,254,740,991 천조 9 참조). 그 숫자 뒤에 이유는 자바 스크립트를 사용한다는 것입니다 배정 밀도 부동 소수점 형식 번호 에 지정된 IEEE 754 만 안전하게 사이의 숫자를 나타낼 수-(2^53 - 1)
및2^53 - 1
.이 맥락에서 안전은 정수를 정확하게 표현하고 정확하게 비교하는 능력을 말합니다. 예를 들어
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2
수학적으로 부정확 한 true로 평가됩니다. Number.isSafeInteger () 참조 를 참조하십시오.Number
MAX_SAFE_INTEGER
의 정적 속성 이므로 생성 한 Number 객체 의 속성이 아니라 항상로 사용합니다 .Number.MAX_SAFE_INTEGER
Chrome 내장 자바 스크립트에서 숫자를 무한대라고하기 전에 약 2 ^ 1024로 이동할 수 있습니다.
자바 스크립트에서 숫자의 표현은 2^53 - 1
.
그러나 , Bitwise operation
에 계산 32 bits ( 4 bytes )
하면 32 비트 교대를 초과 할 경우 비트를 잃어버린 시작합니다 의미합니다.
Scato는 다음과 같이 썼다.
비트 단위 연산에 사용하려는 항목은 0x80000000 (-2147483648 또는 -2 ^ 31)과 0x7fffffff (2147483647 또는 2 ^ 31-1) 사이 여야합니다.
콘솔은 0x80000000은 +2147483648과 같지만 0x80000000 & 0x80000000은 -2147483648과 같다고 알려줍니다.
16 진수는 부호없는 양수이므로 0x80000000 = 2147483648-수학적으로 정확합니다. 부호있는 값으로 만들려면 오른쪽으로 이동해야합니다 : 0x80000000 >> 0 = -2147483648. 대신 1 << 31을 쓸 수도 있습니다.
Firefox 3에는 많은 수의 문제가없는 것 같습니다.
1e + 200 * 1e + 100은 1e + 300까지 벌금을 계산합니다.
Safari도 문제가없는 것 같습니다. (기록을 위해 다른 사람이 이것을 테스트하기로 결정한 경우 Mac에 있습니다.)
이 시간에 두뇌를 잃지 않으면이 값은 64 비트 정수보다 훨씬 큽니다.
100000000000000010 - 1 => 100000000000000020
Node.js와 Chrome은 모두 1024 비트 부동 소수점 값을 사용하는 것으로 보입니다.
Number.MAX_VALUE = 1.7976931348623157e+308
2^53
이라고합니다 MAX_SAFE_INT
.