문제

32 비트 산술을 사용하여 2 개의 64 비트 숫자를 어떻게 추가합니까 ??

도움이 되었습니까?

해결책

가장 중요한 바이트를 먼저 추가하고 캐리를 유지하십시오. LSBS의 캐리를 고려하여 가장 중요한 바이트를 추가하십시오.

; x86 assembly, Intel syntax
; adds ecx:ebx to edx:eax
add eax, ebx
adc edx, ecx

다른 팁

1 자리 산술을 사용하여 2 자리 숫자 두 개를 추가하는 방법을 고려하십시오.

 42
+39
---

먼저 오른쪽 열을 추가합니다. ( "하나"또는 "단위"). 2+9는 11. 11 "오버플로 된"1 자리 산술이므로 10을 "휴대"해야합니다.

 1
 42
+39
---
  1

이제 캐리를 포함하여 왼쪽 "수장"열을 추가합니다. 1+4+3 = 8.

 1
 42
+39
---
 81

8은 10 미만이므로 캐리가 없습니다. 당신은 끝났습니다.

방금 무슨 일이 있었나요? 숫자가 "42"(베이스 10)이라고 말하면 정말

4*10+2

또는 동등하게

4*10^1+2*10^0

( "10^1"과 같이 "a^b"라고 말할 때, 나는 "B의 힘으로 올라 낸 A"를 의미합니다. A 자체를 곱한 B 배. 10^0은 1입니다. 10^1은 10입니다. 10은 10입니다. 10은 10입니다. ^2는 10*10 = 100입니다 ...)

"42"와 "39"를 추가하면

4*10+2+3*10+9

그것은 동일합니다

(4+3)*10+(2+9)*1
(4+3)*10+(11)*1
(4+3)*10+(1*10+1)*1

이제 "11"은 유효한 1 자리 숫자가 아니기 때문에 10 자리에서 10을 가져 와서 TENS 장소에서 1으로 바꿔야합니다.

(4+3)*10+(1)*10+(1)*1
(4+3+1)*10+(1)*1
(8)*10+(1)*1

81입니다.

그렇다면 왜 64 비트 숫자와 32 비트 산술에 대한 질문보다는 이것에 대해 이야기 한 적이 있습니까? 그들은 실제로 정확히 동일하기 때문입니다!

숫자는 0에서 9 사이입니다. "32 비트 번호"는 0에서 2^32-1입니다. (서명되지 않았다고 가정합니다.)

따라서베이스 10에서 일하기보다는 기지 2^32에서 작업합시다. Base 2^32에서는 2^32로 10으로 씁니다. Base 2^32에 64 비트 번호를 작성하면

(x)*10+y

여기서 x와 y는 0과 2^32-1 사이의 숫자에 대한 기호입니다. 그 기호는 비트 링입니다.

두 개의 64 비트 번호를 추가하려면 2^32에서 다음과 같이 분해하십시오.

 a_1*10+a_0
+b_1*10+b_0

이제 기지 2^32에 추가하여베이스 10에 추가하는 것과 똑같은 방식으로 32 비트 산술을 사용하여 추가하는 숫자 산술을 추가하는 대신 바라 봅니다!

64 비트 번호 A를 2 개의 32 비트 번호 A_1 및 A_0으로 어떻게 분할합니까? a를 2^32로 나눕니다. 떠 다니는 지점이 아니라 정수 - 배당금과 나머지를 얻는 곳. 배당금은 A_1이고 나머지는 A_0입니다.

불행히도 64 비트 산술이 필요합니다. 그러나 일반적으로 A_1은 A의 "가장 중요한 절반"이므로 C 스타일 구문에서 :

a_1=(a >> 32)
a_0=(a & 0xFFFFFFFF)

여기서 >>는 올바른 비트 변이이고 & 비트와 관련이 있습니다.

일반적으로 64 비트 추가를 할 수없는 경우 "64 비트 번호"는 실제로 2 개의 32 비트 번호 A_1 및 A_0이됩니다. UINT64_T 산술을 할 수 없다면 UINT64_T가 없습니다!

이 모든 것은 당신이 서명되지 않은 산술을하고 있다고 가정하지만, 표지판을 다루는 것은 여기에서 쉽습니다.

이전에 게시 된 C 코드는 불필요하게 장황합니다.

unsigned a1, b1, a2, b2, c1, c2;

c1 = a1 + b1;
c2 = a2 + b2;

if (c1 < a1)
    c2++;

'if'의 'A1'도 'B1'으로 대체 할 수 있습니다. 오버플로에서 C1은 A1과 B1보다 작습니다.

64 비트 숫자가 (a2,ㅏ1) 및 (b2,비1), 어디 엑스2 높은 32 비트는 서명되지 않은 것으로 간주되며 엑스1 서명되지 않은 상태에서 32 비트가 낮은 다음 두 숫자의 합이 아래에 나와 있습니다.

c1 = a1 + b1

c2 = a2 + b2

if (c1 < a1 || c1 < b1)
   c2 += 1

이렇게 보입니다

/* break up the 64bit number into smaller, 16bit chunks */
struct longint { 
    uint16 word0; 
    uint16 word1;
    uint16 word2;
    uint16 word3;
};

uint16 add(longint *result, longint *a, longint *b)
{
    /* use an intermediate large enough to hold the result
       of adding two 16 bit numbers together. */
    uint32 partial;

    /* add the chunks together, least significant bit first */
    partial = a->word0 + b->word0;

    /* extract thie low 16 bits of the sum and store it */
    result->word0 = partial & 0x0000FFFF;

    /* add the overflow to the next chunk of 16 */
    partial = partial >> 16 + a->word1 + b->word1;
    /* keep doing this for the remaining bits */
    result->word1 = partial & 0x0000FFFF;
    partial = partial >> 16 + a->word2 + b->word2;
    result->word2 = partial & 0x0000FFFF;
    partial = partial >> 16 + a->word3 + b->word3;
    result->word3 = partial & 0x0000FFFF;
    /* if the result overflowed, return nonzero */
    return partial >> 16;
}

실제 하드웨어는 32 비트를 사용하여 한 번에 16 비트를 추가하지 않으며, 추가하기 위해 1 개의 추가 캐리 만 필요하며, 거의 모든 CPU는 추가 작업이 오버플로 흐를 때 캐리 상태 플래그를 가지고 있으므로 사용하는 경우 32 비트 CPU, 2, 32 비트 작업에 64 비트 피연산자를 추가 할 수 있습니다.

거의 모든 프로세서에는 Carry Bit 및 Add-with-Carry 작동이있어 어셈블리에서 프로그래밍하는 경우에만 관심이 있습니다. 더 높은 언어를 사용하는 경우 컴파일러는 정확히 동일한 ADD-with 캐리 작업을 덤프합니다. AVR-GCC는 2 개의 16 비트 번호를 추가 할 때 AVR이 8 비트입니다. 동일한 개념은 더 높은 프로세서에 적용됩니다.

숫자가 레지스터 R1 : R2 및 R3 : R4에 있습니다.

ADD R2,R4 ; first add the two low-bytes, result stored into R2
ADC R1,R3 ; then the two high-bytes and the carry bit, into R1

결과는 R1 : R2에 저장됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top