Javascript에서 ~~ (“double tilde”)의 기능은 무엇입니까?


답변:


248

비트 연산자는 피연산자를 암시 적으로 부호있는 32 비트 정수로 변환하기 때문에 소수점 뒤의 모든 것을 제거합니다. 피연산자가 (부동 소수점) 숫자이든 문자열이든 결과는 숫자입니다.

즉, 다음과 같은 결과를 얻습니다.

function(x) {
  if(x < 0) return Math.ceil(x);
  else return Math.floor(x);
}

x 가-(2 31 )과 2 31-1 사이 인 경우에만 해당됩니다 . 그렇지 않으면 오버플로가 발생하고 숫자가 "랩핑"됩니다.

이것은 함수의 문자열 인수를 숫자로 변환하는 데 유용한 것으로 간주 될 수 있지만 오버플로 가능성과 비 정수와 함께 사용하기에는 올바르지 않기 때문에 "코드 골프"를 제외하고는 사용하지 않을 것입니다 ( 예 : 가독성과 견고성을 희생하면서 프로그램의 소스 코드에서 바이트를 무의미하게 트리밍). +x또는 Number(x)대신 사용 합니다.


이것이 NOT의 NOT 인 방법

예를 들어 숫자 -43.2는 다음과 같습니다.

-43.2 10 = 11111111111111111111111111010101 2

부호있는 (2의 보수) 32 비트 이진수로. (자바 스크립트는 소수점 뒤의 것을 무시합니다.) 비트를 반전 시키면 다음과 같은 결과가 나타납니다.

NOT -43 10 = 00000000000000000000000000101010 2 = 42 10

다시 뒤집 으면 다음이 제공됩니다.

NOT 42 10 = 11111111111111111111111111010101 2 = -43 10

Math.floor(-43.2)음수가 숫자가 아닌 0으로 반올림된다는 점과 다릅니다 . (-44와 같은 바닥 함수는 숫자가 양수인지 음수인지에 관계없이 항상 다음으로 낮은 정수로 내림합니다.)


6
다시 말해서, 잘림 함수~~ 를 작성하기위한 짧은 방법 (및 가능한 좋은 솔루션)입니까 , 그러나 분명히 javascript 입니다.
ruffin

4
JSLint는의 사용에 대해 불평합니다 ~~.
Richard Cook


30

첫 번째 ~ 연산자는 피연산자를 정수로 설정하고 (값을 문자열 또는 부울로 강제 변환 한 후) 가장 낮은 31 비트를 반전시킵니다. 공식적으로 ECMAScript 숫자는 모두 부동 소수점이지만 일부 숫자는 SpiderMonkey 엔진에서 31 비트 정수로 구현됩니다.

이것을 사용하여 1 요소 배열을 정수로 바꿀 수 있습니다. 부동 소수점은 C 규칙에 따라 변환됩니다. 분수 부분의 잘림.

그런 다음 두 번째 ~ 연산자는 비트를 되돌립니다. 따라서 정수를 갖게됩니다. 빈 객체 {}는 true로 평가되는 반면 ~~ {}는 false로 평가되므로 이는 조건문에서 값을 부울로 강제 변환하는 것과 다릅니다.

js>~~"yes"
0
js>~~3
3
js>~~"yes"
0
js>~~false
0
js>~~""
0
js>~~true
1
js>~~"3"
3
js>~~{}
0
js>~~{a:2}
0
js>~~[2]
2
js>~~[2,3]
0
js>~~{toString: function() {return 4}}
4
js>~~NaN
0
js>~~[4.5]
4
js>~~5.6
5
js>~~-5.6
-5

1
여기 Shanti의 모든 예제에 감사드립니다. 정말 도움이되었습니다!
Shane Tomlinson

6
또한~~undefined // 0
경사

1
또한~~null // 0
chovy

기술적으로 주문이 잘못되었습니다. 두 번째 ~는 첫 번째로 설명한 것을 ~수행하고 그 반대도 마찬가지입니다. ~연산자는 단항 연산자이며, 오른쪽에서 왼쪽으로 interpereted있다 ~~X처럼 ~(~X)되지 같은 (~~)X(이 구문 오류가 될 것이다)
yunzen

20

ECMAScript 6에서 ~~ Math.trunc 는 .

소수를 제거하여 숫자의 정수 부분을 반환합니다. 숫자를 반올림하지 않습니다.

Math.trunc(13.37)   // 13
Math.trunc(42.84)   // 42
Math.trunc(0.123)   //  0
Math.trunc(-0.123)  // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN)     // NaN
Math.trunc("foo")   // NaN
Math.trunc()        // NaN

폴리 필 :

function trunc(x) {
    return x < 0 ? Math.ceil(x) : Math.floor(x);
}

6
놀랍게도 ~~는 Math.trunc, jsperf.com/math-trunc-vs-double-bitwise-not-operator 보다 빠릅니다 . 그러나 모든 것이 속도에 관한 것은 아닙니다. 가독성도.
Gajus December

3
~~와 Math.trunc 사이에는 중요한 차이점이 있습니다. 문자열이나 NaN 또는 숫자가 아닌 것을 전달하면 Math.trunc는 NaN을 반환하고 ~~는 항상 숫자를 반환합니다.
Buzinas

Math.trunc가에 따라 소폭 빠른 크롬 59+에서 ~~보다 jsperf.com/math-trunc-vs-double-bitwise-not-operator .
잭 스팀

12

~할 것 같다 -(N+1). 따라서 ~2 == -(2 + 1) == -3-3에서 다시 수행하면 다시 돌아갑니다. ~-3 == -(-3 + 1) == 2아마도 문자열을 원형 방식으로 숫자로 변환합니다.

이 스레드를 참조하십시오 : http://www.sitepoint.com/forums/showthread.php?t=663275

또한 자세한 정보는 http://dreaminginjavascript.wordpress.com/2008/07/04/28/에서 확인할 수 있습니다.


링크 Drackir에 감사드립니다!
Shane Tomlinson


4

약간의 경고입니다. 여기에있는 다른 대답은 나를 곤경에 빠뜨 렸습니다.

의도는 부동 소수점 숫자의 소수점 뒤에있는 것을 제거하는 것이지만 버그가 발생할 수있는 코너 케이스가 있습니다. ~~를 피하는 것이 좋습니다.

첫째, ~~는 매우 큰 숫자에서 작동하지 않습니다.

~~1000000000000 == -727279968

대안으로, 사용 Math.trunc()(Gajus가 언급했듯이 Math.trunc()부동 소수점 숫자의 정수 부분을 반환하지만 ECMAScript 6 호환 JavaScript에서만 사용 가능). 다음을 수행하여 항상 Math.trunc()ECMAScript-6 이외의 환경을위한 고유 한 환경을 만들 수 있습니다 .

if(!Math.trunc){
    Math.trunc = function(value){
        return Math.sign(value) * Math.floor(Math.abs(value));
    }
}

나는 이것을 참조하기 위해 블로그 게시물을 썼습니다 : http://bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html



1

문자열을 숫자로 변환

console.log(~~-1);    // -1
console.log(~~0);     // 0
console.log(~~1);     // 1
console.log(~~"-1");  // -1
console.log(~~"0");   // 0
console.log(~~"1");   // 1
console.log(~~true);  // 1
console.log(~~false); // 0

~ -1은 0입니다

if (~someStr.indexOf("a")) {
  // Found it
} else  {
  // Not Found
}

출처


1

물결표 (~)에는 알고리즘이 있습니다-(N + 1)

예를 들어 :

~0 = -(0+1) = -1
~5 = -(5+1) = -6
~-7 = -(-7+1) = 6

이중 물결표는-(-(N + 1) +1)입니다.

예를 들면 다음과 같습니다.

~~5 = -(-(5+1)+1) = 5
~~-3 = -(-(-3+1)+1) = -3

삼중 물결표는-(-(-(N + 1) +1) +1)입니다.

예를 들면 다음과 같습니다.

~~~2 = -(-(-(2+1)+1)+1) = -3
~~~3 = -(-(-(3+1)+1)+1) = -4
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.