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

오늘 온라인 게임 물리 라이브러리를 확인하고 ~~ 연산자를 발견했습니다. 나는 ~가 비트 NOT이라는 것을 알고 있습니다. ~~를 NOT으로 만들면 같은 값을 줄 것입니다.



답변

비트 연산자는 피연산자를 암시 적으로 부호있는 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와 같은 바닥 함수는 숫자가 양수인지 음수인지에 관계없이 항상 다음으로 낮은 정수로 내림합니다.)


답변

첫 번째 ~ 연산자는 피연산자를 정수로 설정하고 (값을 문자열 또는 부울로 강제 변환 한 후) 가장 낮은 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


답변

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);
}


답변

~할 것 같다 -(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/에서 확인할 수 있습니다.


답변

을 감안할 때 ~NIS -(N+1), ~~N다음입니다 -(-(N+1) + 1). 분명히 깔끔한 속임수로 연결됩니다 .


답변

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

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

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

~~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


답변

이 연산자를 효율적으로 사용하는 방법에 대한 예는 다음과 같습니다.

leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),

출처:

점과의 상호 작용 섹션을 참조하십시오.