루프없이 주어진 숫자의 음수 표현 계산

미샤 모로 쉬코

다음 함수 가 주어진 숫자 음수 표현을 계산하는 이유에 대해 설득력있는 설명이나 수학적 증명을 제공 할 수 있습니까?

function quickNegabinary(number) {
  var mask = 0xAAAAAAAA;
  return ((number + mask) ^ mask).toString(2);
}
m69 'snarky and unwelcoming'

음수 표기법

음수 표기법은 기수 -2를 사용합니다. 이것은 음의 밑 수가있는 모든 숫자 체계에서와 같이 다른 모든 비트가 음의 값을 가짐을 의미합니다.

position:    ...     7    6    5    4    3    2    1    0  

binary:      ...   128   64   32   16    8    4    2    1  
negabinary:  ...  -128  +64  -32  +16   -8   +4   -2   +1  

빠른 변환 방법

빠른 이진 → 음 이진 변환 방법은 0xAAAAAAAA, 또는 이진 ...10101010(음수 표기법으로 음수 값을 갖는 홀수 위치를 나타내는 마스크)을 사용 하여 숫자를 더한 다음 xor (예 : 값 82) :

binary:               01010010  =  82 (binary: 64 + 16 + 2)  
mask:                 10101010  = 170  
bin+mask              11111100  = 252  
(bin+mask) XOR mask:  01010110  =  82 (negabinary: 64 + 16 + 4 - 2)  

작동 원리 : 한 세트 비트

이진 표기법으로 설정된 비트가 하나 뿐인 숫자의 예를 들어 보면 방법이 어떻게 작동하는지 쉽게 알 수 있습니다. 설정 비트가 짝수 위치에 있으면 아무것도 변경되지 않습니다.

binary:               00000100  =   4 (binary: 4)  
mask:                 10101010  = 170  
bin+mask              10101110  = 174  
(bin+mask) XOR mask:  00000100  =   4 (negabinary: 4)  

그러나 설정 비트가 홀수 위치에있는 경우 :

binary:               00001000  =   8 (binary: 8)  
mask:                 10101010  = 170  
bin+mask              10110010  = 178  
(bin+mask) XOR mask:  00011000  =   8 (negabinary: 16 - 8)  

세트 비트는 왼쪽으로 이동하고 (1을 더하여) 원래 값의 음수 (마스크와 XOR-ing)와 결합되어 값이 2n 인 비트가 2n + 1 로 대체됩니다. -2 n .

따라서 빠른 변환 방법은 "매 2를 4-2로, 매 8을 16-8로, 매 32를 64-32로 바꾸는 등"으로 간단하게 생각할 수 있습니다.

작동 원리 : 다중 세트 비트

여러 세트 비트가있는 숫자를 변환 할 때 위에서 설명한 것처럼 하나의 세트 비트로 숫자를 변환 한 결과를 간단히 더할 수 있습니다. 예를 들어 4와 8의 단일 세트 비트 예제 (위 참조)를 결합하여 12를 만듭니다.

binary:               00001100  =  12 (binary: 8 + 4)  
mask:                 10101010  = 170  
bin+mask              10110110  = 182  
(bin+mask) XOR mask:  00011100  =  12 (negabinary: 16 - 8 + 4)  

또는 더 복잡한 예를 들어, 일부 숫자가 전달되는 경우 :

binary:               00111110  =  62 (binary: 32 + 16 + 8 + 4 + 2)  
mask:                 10101010  = 170  
bin+mask              11101000  = 232  
(bin+mask) XOR mask:  01000010  =  62 (negabinary: 64 - 2)  

여기서 일어나는 일은 이진수를 설명하는 합계입니다.

32 + 16 + 8 + 4 + 2

32는 64-32로, 8은 16-8로, 2는 4-2로 변환되므로 합계는 다음과 같습니다.

64-32 + 16 + 16-8 + 4 + 4-2

두 16은 32가되고 두 ​​4는 8이됩니다.

64-32 + 32-8 + 8-2

-32와 +32는 서로를 취소하고 -8과 +8은 ​​서로를 취소하여 다음을 제공합니다.

64-2

또는 음수 산술을 사용합니다.

          +1    +1                 (carry)
     0  1 -1  0  0  0  0  0  =  32 (negabinary: 64 - 32)  
     0  0  0  1  0  0  0  0  =  16 (negabinary: 16)  
     0  0  0  1 -1  0  0  0  =   8 (negabinary: 16 - 8)  
     0  0  0  0  0  1  0  0  =   4 (negabinary: 4)  
  +  0  0  0  0  0  1 -1  0  =   2 (negabinary: 4 - 2)  
     ----------------------  
  =  0  1  0  0  0  0 -1  0  =  62 (negabinary: 64 - 2)  

음수 값

빠른 변환 방법은 2의 보수 표기법의 음수에도 적용됩니다. 예 :

binary:                       11011010  =    -38 (two's complement)  
mask:                         10101010  =    -86 (two's complement)  
bin+mask                      10000100  =   -124 (two's complement)  
(bin+mask) XOR mask:          00101110  =    -38 (negabinary: -32 - 8 + 4 - 2)  
binary:              11111111 11011010  =    -38 (two's complement)  
mask:                10101010 10101010  = -21846 (two's complement)  
bin+mask             10101010 10000100  = -21884 (two's complement)   
(bin+mask) XOR mask: 00000000 00101110  =    -38 (negabinary: -32 - 8 + 4 - 2)  

범위 및 오버플로

n 비트 (여기서 n은 짝수)를 갖는 음수 범위는 다음과 같습니다.

-2/3 × ( 2n -1) → 1/3 × ( 2n -1)

또는 일반적인 비트 심도의 경우 :

 8-bit:            -170  ~             85  
16-bit:         -43,690  ~         21,845  
32-bit:  -2,863,311,530  ~  1,431,655,765  
64-bit:       -1.23e+19  ~       6.15e+18  
80-bit:       -8.06e+23  ~       4.03e+23  

이 범위는 동일한 비트 심도를 가진 부호있는 및 부호없는 표준 정수 표현보다 낮으므로 부호있는 정수와 부호없는 정수는 모두 너무 커서 동일한 비트 심도의 음수 표기법으로 표현할 수 없습니다.

빠른 변환 방법은 -1/6 × (2 n -4) 미만의 음수 값에 대해 오버플로가 발생할 수 있지만 변환 결과는 여전히 정확합니다.

binary:                       11010011 =    -45 (two's complement)  
mask:                         10101010 =    -86 (two's complement)  
bin+mask             11111111 01111101 =   -131 (two's complement)  
overflow truncated:           01111101 =    125 (two's complement)  
(bin+mask) XOR mask:          11010111 =    -45 (negabinary: -128 + 64 + 16 + 4 - 2 + 1)
binary:              11111111 11010011 =    -45 (two's complement)  
mask:                10101010 10101010 = -21846 (two's complement)  
bin+mask             10101010 01111101 = -21891 (two's complement)  
(bin+mask) XOR mask: 00000000 11010111 =    -45 (negabinary: -128 + 64 + 16 + 4 - 2 + 1)

역기능

음수는 덧셈을 반대로하고 마스크로 XOR 처리하여 표준 정수 값으로 다시 변환 할 수 있습니다. 예 :

uint64_t negabinary(int64_t bin) {
    if (bin > 0x5555555555555555) throw std::overflow_error("value out of range");
    const uint64_t mask = 0xAAAAAAAAAAAAAAAA;
    return (mask + bin) ^ mask;
}

int64_t revnegabin(uint64_t neg) {
    // const uint64_t even = 0x2AAAAAAAAAAAAAAA, odd = 0x5555555555555555;
    // if ((neg & even) > (neg & odd)) throw std::overflow_error("value out of range");
    const uint64_t mask = 0xAAAAAAAAAAAAAAAA;
    return (mask ^ neg) - mask;
}

(negabinary () 함수에 의해 생성 된 음수에서만 reverse 함수를 호출하면 오버플로 위험이 없습니다. 그러나 다른 소스의 64 비트 음수는 int64_t 범위 미만의 값을 가질 수 있으므로 오버플로 검사가 필요한.)

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

정수의 이진 표현 계산

분류에서Dev

주어진 길이의 표현 수

분류에서Dev

주어진 정밀도에서 두 숫자 사이의 고유 값 수 계산

분류에서Dev

이진 표현의 2의 보수 값을 계산하는 Windows 10 계산기

분류에서Dev

주어진 숫자 목록의 사 분위수 계산

분류에서Dev

루프없이 문자열의 단어 수 계산

분류에서Dev

주어진 숫자의 밑이 2 인 로그를 계산하는 함수 작성

분류에서Dev

주어진 숫자를 주어진 두 숫자 사이의 백분율로 계산

분류에서Dev

주어진 함수 파이썬의 실행 시간 계산

분류에서Dev

주어진 사용자의 비 수면 프로세스 수 계산

분류에서Dev

주어진 달의 일수 계산

분류에서Dev

foreach 루프없이 주어진 지점보다 작은 배열의 정수를 계산하는 방법이 있습니까?

분류에서Dev

2의 보수 숫자를 이진 표현으로 변환

분류에서Dev

주어진 범위에서 숫자의 최대 계수 합계

분류에서Dev

주어진 수의 상한값을 계산하는 프로그램

분류에서Dev

숫자의 이진 표현 크기

분류에서Dev

배포 데이터 (Mysql / PHP)에서 주어진 월의 working_days 수 계산

분류에서Dev

임베디드 C에서 다음 for 루프에 의해 주어진 지연을 어떻게 계산할 수 있습니까?

분류에서Dev

임베디드 C에서 다음 for 루프에 의해 주어진 지연을 어떻게 계산할 수 있습니까?

분류에서Dev

계수 루프를 사용하여 숫자의 배수를 계산하려면 어떻게해야합니까?

분류에서Dev

주어진 숫자의 계승에서 3의 수를 찾는 프로그램을 작성 중입니다. 사용자의 입력은 숫자입니다.

분류에서Dev

이진 표현식 트리의 값 계산

분류에서Dev

주어진 두 숫자 사이에 4 개의 숫자 (단계) 얻기

분류에서Dev

O (1) 복잡성으로 주어진 범위에서 숫자의 배수를 계산합니까?

분류에서Dev

주어진 항목 범위가 가장 낮은 인덱스의 단일 페이지에 표시되도록 페이지 당 최적의 항목 수 계산

분류에서Dev

주어진 문자열에서 특수 문자 수 계산

분류에서Dev

주어진 언어에서 함수의 비 표현성 증명

분류에서Dev

표준 ML : 주어진 세트의 평균 계산

분류에서Dev

Pygame에서 주어진 좌표로 개체의 점진적인 이동을 구현할 수 있습니까?

Related 관련 기사

  1. 1

    정수의 이진 표현 계산

  2. 2

    주어진 길이의 표현 수

  3. 3

    주어진 정밀도에서 두 숫자 사이의 고유 값 수 계산

  4. 4

    이진 표현의 2의 보수 값을 계산하는 Windows 10 계산기

  5. 5

    주어진 숫자 목록의 사 분위수 계산

  6. 6

    루프없이 문자열의 단어 수 계산

  7. 7

    주어진 숫자의 밑이 2 인 로그를 계산하는 함수 작성

  8. 8

    주어진 숫자를 주어진 두 숫자 사이의 백분율로 계산

  9. 9

    주어진 함수 파이썬의 실행 시간 계산

  10. 10

    주어진 사용자의 비 수면 프로세스 수 계산

  11. 11

    주어진 달의 일수 계산

  12. 12

    foreach 루프없이 주어진 지점보다 작은 배열의 정수를 계산하는 방법이 있습니까?

  13. 13

    2의 보수 숫자를 이진 표현으로 변환

  14. 14

    주어진 범위에서 숫자의 최대 계수 합계

  15. 15

    주어진 수의 상한값을 계산하는 프로그램

  16. 16

    숫자의 이진 표현 크기

  17. 17

    배포 데이터 (Mysql / PHP)에서 주어진 월의 working_days 수 계산

  18. 18

    임베디드 C에서 다음 for 루프에 의해 주어진 지연을 어떻게 계산할 수 있습니까?

  19. 19

    임베디드 C에서 다음 for 루프에 의해 주어진 지연을 어떻게 계산할 수 있습니까?

  20. 20

    계수 루프를 사용하여 숫자의 배수를 계산하려면 어떻게해야합니까?

  21. 21

    주어진 숫자의 계승에서 3의 수를 찾는 프로그램을 작성 중입니다. 사용자의 입력은 숫자입니다.

  22. 22

    이진 표현식 트리의 값 계산

  23. 23

    주어진 두 숫자 사이에 4 개의 숫자 (단계) 얻기

  24. 24

    O (1) 복잡성으로 주어진 범위에서 숫자의 배수를 계산합니까?

  25. 25

    주어진 항목 범위가 가장 낮은 인덱스의 단일 페이지에 표시되도록 페이지 당 최적의 항목 수 계산

  26. 26

    주어진 문자열에서 특수 문자 수 계산

  27. 27

    주어진 언어에서 함수의 비 표현성 증명

  28. 28

    표준 ML : 주어진 세트의 평균 계산

  29. 29

    Pygame에서 주어진 좌표로 개체의 점진적인 이동을 구현할 수 있습니까?

뜨겁다태그

보관