이 숫자는 -2의 정확한 거듭 제곱입니까 : (매우) 하드 모드


26

이것은 최근 도전의 버전입니다. 이 숫자는 정수 -2입니까? 문제의 흥미로운 특성을 강조하고 도전을 더욱 어렵게하기 위해 고안된 다른 기준을 사용합니다. 여기 에 몇 가지 고려 사항이 있습니다 .

Toby가 관련 질문에서 훌륭하게 언급 한 도전은 다음과 같습니다.

정수가 2의 정확한 거듭 제곱인지 여부를 결정하는 영리한 방법이 있습니다. 더 이상 흥미로운 문제는 아니므로 주어진 정수가 -2 의 정확한 거듭 제곱인지 여부를 결정하십시오 . 예를 들면 다음과 같습니다.

-2 => yes: (-2)¹
-1 => no
0 => no
1 => yes: (-2)⁰
2 => no
3 => no
4 => yes: (-2)²

규칙 :

  • 정수는 부호있는 64 비트이며 2의 보수입니다. 이것은 작업 할 수 있는 유일한 데이터 유형입니다.
  • 다음 작업 만 사용할 수 있습니다. 이들 각각은 하나의 작업으로 계산됩니다.
    • n << k, n >> k: 좌 / 우측 시프트 n에 의해 k비트. 부호 비트가 오른쪽으로 확장됩니다.
    • n >>> k: 오른쪽으로 이동하지만 부호 비트를 확장하지 않습니다. 0이 이동합니다.
    • a & b, a | b, a ^ b: 비트 단위 AND, OR, XOR.
    • a + b, a - b, a * b:, 빼기, 곱하기 추가합니다.
    • ~b: 비트 단위 반전.
    • -b: 2의 보수 부정.
    • a / b, a % b: 나누기 (정수 몫, 0을 향해 반올림) 및 모듈로.
      • 음수의 모듈은 규칙을 사용하여 C99에 지정을 : (a/b) * b + a%b동일하여야한다 a. 그래서 5 % -3입니다 2, 그리고 -5 % 3있다 -2:
      • 5 / 3is 1, 5 % 3is 2, 1 * 3 + 2 = 5
      • -5 / 3-는 * -1,- -5 % 3-2* 1 + 3 + -2 = -5입니다.
      • 5 / -3이고 -1, 5 % -3이며 2, -1 * -3 + 2 = 5.
      • -5 / -3is 1, -5 % -3is -2, 1 * -3 + -2 = -5.
      • 파이썬의 //바닥 나누기 연산자는 여기에서 나누기의 "0을 향한 반올림"속성을 %만족하지 않으며 , 파이썬 연산자는 요구 사항도 충족하지 않습니다.
    • 배정은 작업으로 계산되지 않습니다. C에서와 마찬가지로, 할당은 할당 한 후 왼쪽의 가치 평가 : a = (b = a + 5)세트 ba + 5, 다음 세트 ab하나 개의 작업으로, 그리고 수를.
    • 복합 할당은 a += b수단 으로 사용될 a = a + b수 있으며 하나의 연산으로 계산됩니다.
  • 정수 상수를 사용할 수 있지만 아무것도 계산하지 않습니다.
  • 작업 순서를 지정하는 괄호는 허용됩니다.
  • 함수를 선언 할 수 있습니다. 함수 선언은 64 개 비트 정수는 것을 당신 만 참고 편리 어떤 스타일에있을 수 있습니다 유효한 데이터 유형입니다. 함수 선언은 연산으로 계산되지 않지만 함수 호출 은 하나로 계산됩니다. 또한, 명확하게하기 위해 : 함수는 여러 return문장을 포함 할 수 있으며 return어느 시점에서나 허용됩니다. return자체는 조작으로 간주하지 않습니다.
  • 무료로 변수를 선언 할 수 있습니다.
  • 당신은 사용할 수 있습니다 while루프,하지만 당신은 사용할 수 없습니다 iffor. 에 사용되는 연산자while조건에 점수에 포함됩니다. while루프는 조건 이 0이 아닌 값으로 평가되는 한 실행됩니다 (이 개념을 가진 언어의 "거짓"0은 올바른 결과가 아닙니다). 조기 복귀가 허용되어 있기 때문에, 당신은 사용할 수 있습니다 break뿐만 아니라,
  • 오버 플로우 / 언더 플로우가 허용되며 값 클램핑이 수행되지 않습니다. 작업이 실제로 올바르게 발생한 것처럼 처리 된 다음 64 비트로 잘립니다.

득점 / 승리 기준 :

입력이 -2의 거듭 제곱이면 0이 아닌 값을 생성하고 그렇지 않으면 0을 생성해야합니다.

이것은 입니다. 점수는 런타임에 실행되는 총 작업 수가 아니라 코드에 존재하는 총 작업 수 (위에 정의 된대로) 입니다. 다음 코드 :

function example (a, b) {
    return a + ~b;
}

function ispowerofnegtwo (input) {
    y = example(input, 9);
    y = example(y, 42);
    y = example(y, 98);
    return y;
}

함수에 2 개, 함수 호출에 3 개의 5 가지 작업이 있습니다.

결과를 어떻게 표현하든, 언어에서 편리한 것을 사용하고, 결과를 변수에 저장하거나, 함수에서 반환하거나, 무엇이든 반환하십시오.

승자는 명백히 정확하고 (필요한 경우 우연한 또는 공식적인 증거를 제공하는) 게시물이며 위에 설명 된대로 가장 낮은 점수를받습니다.

보너스 매우 어려운 모드 도전!

파티에서 사람들에게 깊은 인상을 줄 수있는 능력을 제외하고는 전혀 아무것도 얻지 못할 경우 while루프 를 사용하지 않고 답변을 제출하십시오 ! 이것들이 충분히 제출된다면 나는 우승 그룹을 두 가지 범주 (루프 유무에 관계없이)로 나누는 것을 고려할 수도 있습니다.


참고 : 32 비트 정수만 지원하는 언어로 솔루션을 제공하려는 경우 설명에서 64 비트 정수에 대해 여전히 올바르다는 것을 충분히 정당화 할 수 있습니다.

또한 : 특정 언어 별 기능은 규칙을 회피하지는 않지만 위의 규칙에 따라 언어가 동작하도록 강요해야하는 경우 무료로 허용 될 수 있습니다 . 예를 들어, (고려 된), 나는 조건이 전체적으로 적용될 때 루프 에서 0이 아닌 0을 비교 하는 것을 허용 할 것이다 while. 이러한 유형의 것을 활용하려는 명확한 시도는 허용되지 않습니다 . 예를 들어 "truthy"0 또는 "undefined"값의 개념은 위의 규칙 세트에 없으므로 신뢰할 수 없습니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Dennis

@hvd이 글을 읽는다면 : 답을 완전히 삭제 취소해야합니다! 그것이 인상적이지 않더라도 m ^= s 그것이 옳다고 가정하면 , 그것을 더 향상시키기 위해 대체를하는 것이 완전히 괜찮을 것이라고 생각합니다.
Jason C

어떻게 이해를 허용 할 수 있도록 않습니다 whilebreak하지만 if? if (x) { ... }와 같습니다 while (x) { ... break; }.
R ..

@R .. 100 % 이해가되지 않으며 ( break초기 수익은 유감스러운 부분 임) 긴 이야기이며 미래의 도전에 대한 규칙에서 배운 교훈입니다. 항상 "보너스"버전이 있습니다! :)
Jason C

1
if그리고 for허용되지 않습니까? int x=condition; while (x) { ... x=0; }무료이며 더 많은 코드입니다. c-style도 마찬가지 for입니다.
Qwertiy

답변:


35

C ++, 15 개 작업

while루프가 전체 챌린지를 파괴 할 때 왜 루프가 허용 되는지 모르겠습니다 . 여기에 아무런 대답이 없습니다 :

int64_t is_negpow2(int64_t n) {
    int64_t neg = uint64_t(n) >> 63; // n >>> 63
    n = (n ^ -neg) + neg; // if (n < 0) n = -n;
    int64_t evenbits = n & int64_t(0xaaaaaaaaaaaaaaaaull >> neg);
    int64_t n1 = n - 1;
    int64_t pot = n & n1;
    int64_t r = pot | (n1 >> 63) | evenbits;
    return ~((r | -r) >> 63); // !r
}

while루프가 왜 모든 도전을 파괴 합니까?
Mr. Xcoder

10
@ Mr.Xcoder 간단한 비트 단위 작업 while으로 모든 작업을 수행하는 것이 쉽지 않기 때문입니다 .
orlp

while 루프에 정적 수 n또는 기타 에 대해 루프에서 실행 된 횟수와 작업 횟수를 곱하지 않으면 의미하지 않습니다 .
Magic Octopus Urn

나는 이것에 대해 여기에 의견을 남겼다 .
Jason C

@JasonC 그것은 부호 비트없이 올바른 시프트를 사용해야했기 때문입니다. 코드를 편집 uint64_t했습니다. 부호 확장없이 올바른 이동을 얻을 수있는 유일한 방법이기 때문에 사용 합니다.
orlp

25

파이썬 2 , 3 연산

def f(n):
 while n>>1:
  while n&1:return 0
  n=n/-2
 return n

온라인으로 사용해보십시오!

동작은 >>, &, /.

아이디어는 반복적으로 -2로 나누는 것입니다. -2 체인의 힘은 1로 줄어 듭니다 -8 -> 4 -> -2 -> 1. 우리가를 치면 1수락하십시오. 치기 전에 홀수를 쳤다 1면 거절하십시오. 우리는 또한 거부해야한다 0.

while n>>1:될 때까지 루프 n0 또는 루프 나누기, 1입니다 n자체가 반환되고, 1Truthy 출력이며 0Falsey 하나. 루프 내에서 반복적으로 적용 n -> n/-2을 거부하고 홀수를 거부합니다 n.

/이 값은 짝수 값에만 사용 되므로 반올림 동작이 작동하지 않습니다. 따라서 파이썬이 스펙과 다르게 반올림하는 것은 중요하지 않습니다.


좋은. 알고리즘의 영리한 논리와 조건을 비트 연산으로 결합하는 훌륭한 작업. 또한
C

while n&1대신에 if n&1?
Mark Ransom

2
@MarkRansom 도전은 허용하지 않습니다 if.
xnor

아하. 매우 영리한 대체입니다.
Mark Ransom

1
@EvSunWoodard 스코어링은 실행 중 호출 횟수가 아닌 코드의 연산자 수이며 입력에 따라 다릅니다. "이것은 원자 코드 골프입니다. 점수는 코드에있는 총 연산 수입니다. "
xnor

11

녹, 14 12 가지 작업 (루프 없음)

최적화 ( -O)가 필요 하거나 -C overflow-checks=no패닉 대신 오버플로 빼기를 활성화해야합니다.

fn is_power_of_negative_2(input: i64) -> i64 {
    let sign = input >> 63;
    // 1 op
    let abs_input = (input ^ sign) - sign;
    // 2 ops
    let bad_power_of_two = sign ^ -0x5555_5555_5555_5556; // == 0xaaaa_aaaa_aaaa_aaaa
    // 1 op
    let is_not_power_of_n2 = abs_input & ((abs_input - 1) | bad_power_of_two);
    // 3 ops 
    let is_not_power_of_n2 = (is_not_power_of_n2 | -is_not_power_of_n2) >> 63;
    // 3 ops 
    input & !is_not_power_of_n2
    // 2 ops
}

(명확히하려면 : !x이다 비트 단위 NOT 여기없는 논리 NOT)

테스트 사례 :

#[test]
fn test_is_power_of_negative_2() {
    let mut value = 1;
    for _ in 0 .. 64 {
        assert_ne!(0, is_power_of_negative_2(value), "wrong: {} should return nonzero", value);
        value *= -2;
    }
}

#[test]
fn test_not_power_of_negative_2() {
    for i in &[0, -1, 2, 3, -3, -4, 5, -5, 6, -6, 7, -7, 8, 1<<61, -1<<62, 2554790084739629493, -4676986601000636537] {
        assert_eq!(0, is_power_of_negative_2(*i), "wrong: {} should return zero", i);
    }
}

온라인으로 사용해보십시오!


아이디어는 | x | 2의 거듭 제곱입니다 ( (y & (y - 1)) == 0평소대로 사용). x가 2의 거듭 제곱 인 경우 x >= 0, (1) 언제 2의 짝수 거듭 제곱인지, (2)x < 0 의 짝수 거듭 제곱이어야하는지, 의 홀수 거듭 제곱이어야하는지 추가로 확인 &합니다. bad_power_of_two"마스크 0x… aaaa 일 때 x >= 0(균일 한 힘인 경우 에만 0을 생성) 또는 0x… 5555 일 때 x < 0.


나는 ~((r | -r) >> 63)내 대답을 고치기 위해 당신의 트릭을 훔쳤다 .
orlp

6

하스켈, 2 3 작업

import Data.Bits (.&.)

f 0 = False
f 1 = True
f n | n .&. 1 == 0 = f (n `div` -2)
f n | otherwise    = False

재귀 함수를 정의합니다 f(n). 사용되는 연산은 함수 호출 ( f), 나누기 ( div) 및 비트 단위 ( .&.)입니다.

Haskell에 루프 명령문이 없기 때문에 루프가 없습니다 :-)


4
루프를 사용하지 않는 Haskell 솔루션이 "기회 주의자 (Opportunist)"라는 이름의 누군가에 의해 제공된다는 것이 왜 놀라지 않습니까? =)
Cort Ammon-복직 모니카

1
아주 [정보 주저 f 0, f 1, f n ...그들이 본질적으로하기 때문에 여기에 if다시, 내가 할 수 않았지만 ', 변장이야 while+ breakreturn는 공정 보인다 있도록,의. 내 규칙 세트가 우연히 해석에 개방되어 있다는 점을 활용하는 것처럼 보이지만 좋은 해결책입니다.
Jason C

3
특히 |s는 특히 공중에 있습니다. 즉, 이것은 논쟁의 여지가없는 방식으로 하나의 특정 규칙을 위반합니다. 비교 ==는 허용되지 않습니다. 이 코드의 내 해석이 맞다면 참고하지만, 논리 값의 사용은 여기에 않는 결과를 변경 표시되지 않습니다 자신의 위치에서 임의의 정수 값을 대체로 인정 나타나고, 그들은 더 많은 최종 프리젠 테이션 양식입니다.
Jason C

@JasonC 난 단지 사용하고 있습니다 ==에서 전송할 다른 방법이 없기 때문 IntBool나 하스켈 "Truthy가". 패턴 일치와 경비원이 "아니오 if"규칙 을 위반하는지 여부 는 귀하의 전화입니다 ;-)
기회

18
패턴 일치를 사용하면 0 연산을 사용하여 모든 64 비트 정수에 대한 결과를 하드 코딩 할 수 있습니다.
xnor

5

파이썬 3, 10 또는 11 9 연산

def g(x):
 while x:
  while 1 - (1 + ~int(x - -2 * int(float(x) / -2))) & 1: x /= -2
  break
 while int(1-x):
     return 0
 return 5  # or any other value

반환 5의 힘에 -2, 0그렇지 않으면


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Dennis

5

C, 5 회

long long f(long long x){
    x=x ^ ((x & 0xaaaaaaaaaaaaaaaa) * 6);
    while(x){
        while(x&(x-1))
            return 0;
        return 1;
    }
    return 0;
}

루프없는 C, 10 개의 연산

long long f(long long x){
    x = x ^ ((x & 0xaaaaaaaaaaaaaaaa) * 6);
    long long t = x & (x-1);
    return (((t-1) & ~t) >> 63) * x;
}

C, 1 회

long long f(long long x){
    long long a0=1, a1=-2, a2=4, a3=-8, a4=16, a5=-32, a6=64, a7=-128, a8=256, a9=-512, a10=1024, a11=-2048, a12=4096, a13=-8192, a14=16384, a15=-32768, a16=65536, a17=-131072, a18=262144, a19=-524288, a20=1048576, a21=-2097152, a22=4194304, a23=-8388608, a24=16777216, a25=-33554432, a26=67108864, a27=-134217728, a28=268435456, a29=-536870912, a30=1073741824, a31=-2147483648, a32=4294967296, a33=-8589934592, a34=17179869184, a35=-34359738368, a36=68719476736, a37=-137438953472, a38=274877906944, a39=-549755813888, a40=1099511627776, a41=-2199023255552, a42=4398046511104, a43=-8796093022208, a44=17592186044416, a45=-35184372088832, a46=70368744177664, a47=-140737488355328, a48=281474976710656, a49=-562949953421312, a50=1125899906842624, a51=-2251799813685248, a52=4503599627370496, a53=-9007199254740992, a54=18014398509481984, a55=-36028797018963968, a56=72057594037927936, a57=-144115188075855872, a58=288230376151711744, a59=-576460752303423488, a60=1152921504606846976, a61=-2305843009213693952, a62=4611686018427387904, a63=-9223372036854775807-1, a64=0;
    while(a0){
        long long t = x ^ a0;
        long long f = 1;
        while(t){
            f = 0;
            t = 0;
        }
        while(f)
            return 1;
        a0=a1; a1=a2; a2=a3; a3=a4; a4=a5; a5=a6; a6=a7; a7=a8; a8=a9; a9=a10; a10=a11; a11=a12; a12=a13; a13=a14; a14=a15; a15=a16; a16=a17; a17=a18; a18=a19; a19=a20; a20=a21; a21=a22; a22=a23; a23=a24; a24=a25; a25=a26; a26=a27; a27=a28; a28=a29; a29=a30; a30=a31; a31=a32; a32=a33; a33=a34; a34=a35; a35=a36; a36=a37; a37=a38; a38=a39; a39=a40; a40=a41; a41=a42; a42=a43; a43=a44; a44=a45; a45=a46; a46=a47; a47=a48; a48=a49; a49=a50; a50=a51; a51=a52; a52=a53; a53=a54; a54=a55; a55=a56; a56=a57; a57=a58; a58=a59; a59=a60; a60=a61; a61=a62; a62=a63; a63=a64;
    }
    return 0;
}

2
오, 그 마지막 것은 단지 악입니다. 좋은.
Jason C

4

조립, 1 회

.data

    .space 1         , 1 # (-2)^31
    .space 1610612735, 0
    .space 1         , 1 # (-2)^29
    .space 402653183 , 0
    .space 1         , 1 # (-2)^27
    .space 100663295 , 0
    .space 1         , 1 # (-2)^25
    .space 25165823  , 0
    .space 1         , 1 # (-2)^23
    .space 6291455   , 0
    .space 1         , 1 # (-2)^21
    .space 1572863   , 0
    .space 1         , 1 # (-2)^19
    .space 393215    , 0
    .space 1         , 1 # (-2)^17
    .space 98303     , 0
    .space 1         , 1 # (-2)^15
    .space 24575     , 0
    .space 1         , 1 # (-2)^13
    .space 6143      , 0
    .space 1         , 1 # (-2)^11
    .space 1535      , 0
    .space 1         , 1 # (-2)^9
    .space 383       , 0
    .space 1         , 1 # (-2)^7
    .space 95        , 0
    .space 1         , 1 # (-2)^5 = -32
    .space 23        , 0
    .space 1         , 1 # (-2)^3 = -8
    .space 5         , 0
    .space 1         , 1 # (-2)^1 = -2
    .space 1         , 0
dataZero:
    .space 1         , 0
    .space 1         , 1 # (-2)^0 = 1
    .space 2         , 0
    .space 1         , 1 # (-2)^2 = 4
    .space 11        , 0
    .space 1         , 1 # (-2)^4 = 16
    .space 47        , 0
    .space 1         , 1 # (-2)^6 = 64
    .space 191       , 0
    .space 1         , 1 # (-2)^8
    .space 767       , 0
    .space 1         , 1 # (-2)^10
    .space 3071      , 0
    .space 1         , 1 # (-2)^12
    .space 12287     , 0
    .space 1         , 1 # (-2)^14
    .space 49151     , 0
    .space 1         , 1 # (-2)^16
    .space 196607    , 0
    .space 1         , 1 # (-2)^18
    .space 786431    , 0
    .space 1         , 1 # (-2)^20
    .space 3145727   , 0
    .space 1         , 1 # (-2)^22
    .space 12582911  , 0
    .space 1         , 1 # (-2)^24
    .space 50331647  , 0
    .space 1         , 1 # (-2)^26
    .space 201326591 , 0
    .space 1         , 1 # (-2)^28
    .space 805306367 , 0
    .space 1         , 1 # (-2)^30
    .space 3221225471, 0
    .space 1         , 1 # (-2)^32

.globl isPowNeg2
isPowNeg2:
    movl dataZero(%edi), %eax
    ret

큰 조회 테이블을 사용하여 숫자가 2의 거듭 제곱인지 확인합니다. 64 비트로 확장 할 수 있지만 많은 양의 데이터를 저장할 컴퓨터를 찾는 것은 독자에게 연습으로 남습니다.


1
테이블 인덱싱은 허용되는 작업 중 하나가 아닙니다.
R ..

1
또한 이것은 64 비트로 확장 할 수 없습니다. :-)
R ..

실제로 테이블을 인덱싱하는 것은하지 않은 목적으로 현재의 규정에 따라 허용 될 수 있습니다. 스칼라 의도로 "변수를 선언 할 수 있습니다"와 "정수 리터럴을 지정할 수 있습니다"를 지정했으며 의미 적으로 이것은 배열입니다. 어셈블러의 맥락에서 "추가"라고 부를 수 있지만 오퍼레이션은 ... :)
Jason C

3

C, 31 회

라이브 데모

내 생각은 간단합니다. 2의 거듭 제곱이면 로그가 짝 수면 양수 여야합니다. 그렇지 않으면 로그가 홀수 여야합니다.

int isPositive(int x) // 6
{
    return ((~x & (~x + 1)) >> 31) & 1;
}

int isPowerOfTwo(int x) // 5
{
    return isPositive(x) & ~(x & (x-1));
}

int log2(int x) // 3
{
    int i = (-1);

    while(isPositive(x))
    {
        i  += 1;
        x >>= 1;
    }

    return i;
}

int isPowerOfNegativeTwo(int x) // 17
{
    return (  isPositive(x) &  isPowerOfTwo(x) & ~(log2(x) % 2) )
         | ( ~isPositive(x) & isPowerOfTwo(-x) & (log2(-x) % 2) );
}

1
당신은 실제로 당신이 생각하는 것보다 낫습니다. 함수 호출은 함수의 연산자 수가 아닌 1로만 계산됩니다. 따라서, 정확하게 계산 (더블 체크)하면 isPositive의 경우 6, isPowerOfTwo의 경우 5, log2의 경우 3, isPowerOfNegativeTwo = 31의 경우 17과 같은 것이 있습니다.
Jason C

1

C, 7 회

int64_t is_power_of_neg2(int64_t n)
{
    int64_t x = n&-n;
    while (x^n) {
        while (x^-n)
            return 0;
        return x & 0xaaaaaaaaaaaaaaaa;
    }
    return x & 0x5555555555555555;
}

또는:

조건에 따라 루프없이 C, 13 개의 연산

int64_t is_power_of_neg2(int64_t n)
{
    int64_t s = ~(n>>63);
    int64_t a = ((n/2)^s)-s;
    int64_t x = n&-(uint64_t)n; // Cast to define - on INT64_MIN.
    return ~(a/x >> 63) & x & (0xaaaaaaaaaaaaaaaa^s);
}

설명:

  • n&-n 가장 낮은 설정 비트를 생성합니다 n .
  • a부정 된 절대 값은 n/2반드시 음수이므로/2 은 부정의 오버플로를 배제 .
  • a/xa정확히 2의 거듭 제곱 인 경우에만 0 입니다. 그렇지 않으면 적어도 하나의 다른 비트가 설정되고x 되고 가장 낮은 비트 음수 결과가 나타납니다.
  • ~(a/x >> 63)다음 모든 것들의 경우 비트 마스크 산출 n하거나 -n, 그렇지 않으면 모두 0이 2의 거듭 제곱입니다.
  • ^s가 마스크에 적용되어의 n거듭 제곱인지 확인합니다 -2.

1

PHP, 3 가지 연산

삼항이며 if허용되지 않습니다. 남용하자 while:

function f($n)
{
    while ($n>>1)               # 1. ">>1"
    {
        while ($n&1)            # 2. "&1"
            return 0;
        return f($n/-2|0);      # 3. "/-2" ("|0" to turn it into integer division)
    }
    return $n;
}
  1. $n>>1: 숫자가 0 또는 1이면 숫자를 반환
  2. $n&1: 숫자가 홀수이면 0을 반환
  3. else 테스트 $n/-2(+로 캐스트)

0

자바 스크립트 ES6, 7 가지 작업

x=>{
  while(x&1^1&x/x){
    x/=-2;x=x|0
  }
  while(x&0xfffffffe)x-=x
  return x
}

온라인으로 사용해보십시오!

설명

while(x&1^1&x/x)

x! = 0 및 x % 2 == 0 4 ops
x / x는 x가 0이 아닌 한 1과 같습니다 (0/0은 NaN으로 거짓으로 평가됨)
& 비트 단위이고
x & 1 ^ 1은 1과 같습니다 x가 짝수 인 경우 (x 및 1) xor 1

x/=-2;x=x|0

이것은 질문 1 op에 의해 정의 된 나눗셈의 형태입니다

while(x&0xfffffffe)  

x! = 1 및 x! = 0 1 op
동안 x == 0 또는 x == 1 인 경우 두 값이 반환 값이고 무한 루프를 입력하면 생산적이지 않으므로 종료해야했습니다. 이것은 이론적으로 16 진수를 늘림으로써 더 큰 값으로 확장 될 수 있습니다. 현재 ± 2 ^ 32-1까지 작동

x-=x

x를 0 1 op로 설정
0 ops에 return 0을 사용할 수는 있지만 다른 명령문으로 인해 중단되는 while 루프는 부정 행위처럼 느껴집니다.

return x

x를 반환합니다 (-2의 거듭 제곱이면 1, 그렇지 않으면 0)

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