부동소수점 정렬: 덧셈기보다 주변 회로가 바쁜 이유
부동소수점 덧셈기에서 정수 덧셈기보다 주변 회로가 크게 보이는 이유는 무엇일까. 두 입력의 숫자 자리가 처음부터 맞아 있지 않기 때문이다. 부동소수점 정렬은 서로 다른 지수의 유효숫자를 같은 자리 기준으로 옮겨, 덧셈할 비트의 가중치를 맞추는 과정이다.
정상적인 이진 부동소수점 값은 부호, 지수와 유효숫자로 생각할 수 있다. 예를 들어 1.5는 1.1₂×2⁰, 0.09375는 1.1₂×2⁻⁴다. 유효숫자만 더하면 둘 다 1.1이지만 실제 숫자의 크기는 다르다.
작은 지수를 큰 지수에 맞추기
지수 차이는 4다. 작은 값의 유효숫자를 오른쪽으로 네 자리 옮기면 같은 2⁰ 기준에서 다음과 같이 쓸 수 있다.
1.1000000 × 2^0
+ 0.0001100 × 2^0
= 1.1001100 × 2^0
정확한 합은 1.59375다. 유효숫자를 그대로 더한 11.0₂가 답이 아닌 이유는 bit 위치가 같은 가중치를 뜻하지 않았기 때문이다. 정렬은 숫자를 바꾸지 않으면서 표현의 기준을 맞춘다.
실제 회로는 입력 지수를 비교하고, 큰 입력과 작은 입력을 정해 작은 쪽을 이동시킨다. 이동량은 지수 차이에서 온다. 같은 덧셈기라도 데이터 선택과 가변 이동 경로가 앞에 붙어 있어, 덧셈 본체만으로 전체 지연을 설명할 수 없다.
Berkeley HardFloat 문서에서 addRecFNToRaw는 최종 반올림 전의 결과를 별도 표현으로 내보낸다. 정렬·연산의 내부 결과와 저장 형식의 최종 결과를 분리하는 설계 사례다. 문서의 raw 출력과 round 모듈 사이의 관계를 보면, 연산 전 입력 형식과 중간 정보의 폭을 같게 두지 않는 이유를 이해할 수 있다.
이동하면서 사라지는 비트도 결과를 바꾼다
출력 유효숫자가 제한되어 있으면 정확한 합의 낮은 비트를 모두 저장할 수 없다. 하지만 정렬 단계에서 낮은 비트를 바로 버리면 최종 반올림에 필요한 정보까지 사라질 수 있다.
설명용으로 유효숫자 전체가 5비트인 작은 형식을 생각하자. 1.59375의 이진 표현은 1.1001100이다. 5비트로 남길 후보는 1.1001=1.5625와 1.1010=1.625다. 정확한 값은 그 중간에 있다. nearest-even이라면 마지막 보존 비트가 0인 1.1010을 선택한다.
이 예에서는 저장하지 않을 낮은 비트가 “정확히 중간”이라는 사실을 알려 준다. 큰 지수 차이로 많은 비트를 이동하더라도, 그중 어느 비트라도 1이었는지 같은 요약 정보는 반올림을 바꿀 수 있다. 작은 입력이 출력 자리에 직접 나타나지 않는다고 영향을 항상 무시할 수는 없다.
5비트 형식은 원리 설명용이며 HardFloat의 특정 parameter 조합에 대한 시험 결과가 아니다. 실제 구현은 자신의 지원 형식과 반올림 규칙에 맞춰 충분한 중간 비트와 요약 정보를 유지해야 한다.
빼기에서는 결과를 다시 왼쪽으로 옮길 수 있다
부호가 다른 값을 더하는 경우에는 유효숫자의 차이를 계산하게 된다. 가상의 정확한 입력 1.5와 −1.4375를 더하면 결과는 0.0625, 즉 1.0₂×2⁻⁴다. 입력의 기준 지수는 0이었지만 서로 큰 부분을 상쇄한 뒤 첫 1이 낮은 자리에 남는다.
그래서 연산 이후에는 첫 유효 1의 위치를 찾아 왼쪽으로 정규화하고 지수를 조정할 수 있다. 입력 정렬은 작은 값을 오른쪽으로 이동하는 과정이고, 상쇄 결과의 정규화는 결과를 다시 적절한 자리에 놓는 과정이다. 둘을 단순히 “shift 하나”로 뭉치면 각 이동량의 원인을 놓친다.
두 값이 완전히 상쇄되어 0이면 정상값의 첫 1을 찾을 수 없다. 0 처리와 부호 규칙도 필요하다. 아주 작은 결과는 subnormal 범위에 들어갈 수 있으므로, 정상값의 숨은 첫 1을 항상 가정하는 내부 표현은 해당 변환을 포함해야 한다.
정렬 회로를 줄일 때 지켜야 할 관계
지수 차이가 충분히 크면 최종 결과의 주요 비트에 작은 입력이 직접 더해지지 않을 수 있다. 이때 큰 이동량을 더 작게 제한하거나 낮은 정보를 요약하는 최적화가 가능하다. 다만 반올림 방향과 부호, 상쇄 가능성을 포함해 동일한 결과를 내야 한다.
round-toward-positive처럼 방향성 반올림을 사용하면 아주 작은 양의 입력도 결과를 한 단계 올리는 이유가 될 수 있다. “지수가 크게 다르면 작은 수는 무조건 무시”라는 설명은 반올림 계약이 빠져 있다. 최적화의 근거는 크기 차이 자체보다 최종 관측 결과의 동치여야 한다.
파이프라인을 넣는다면 지수 비교 결과, 부호와 특별값 정보도 유효숫자와 같은 요청에 붙여 전달해야 한다. 한 입력의 이동된 유효숫자에 다른 입력의 지수 차이가 붙으면 각각의 부분 회로는 정상인데 합은 틀린다.
부동소수점 정렬의 목적은 숫자를 작게 만드는 것이 아니라 비트가 같은 가중치를 갖게 만드는 것이다. 정렬 전에는 지수의 기준을, 정렬 중에는 잃는 비트의 의미를, 연산 후에는 첫 유효 자리와 지수를 함께 지켜야 한다. 덧셈기 주변의 많은 회로는 이 하나의 숫자 계약을 보존하기 위해 존재한다.