Altifigence Academy

3 / 20 · 개념

고정소수점 출력 정책

입력 스케일, 음수 반올림, 포화와 랩어라운드를 구분합니다.

비트는 정수, 의미는 스케일

고정소수점 값 x를 정수 X와 소수 비트 수 F로 표현하면 x=X/2^F입니다. 이 과정에서는 모든 A와 B에 같은 F를 쓰고, 곱과 누산기에는 2F개의 소수 비트가 있다고 약속합니다. 누산기의 원시 정수 S를 입력과 같은 스케일로 되돌리려면 2^F로 나누어야 합니다. 스케일을 바꾸는 시점은 전체 K항을 누산한 뒤 한 번입니다. 항마다 먼저 버리면 작은 항들이 모여 만드는 결과를 잃습니다.

F=4에서 [1.5,−0.5]는 원시 정수 [24,−8], [0.25,2.0]은 [4,32]입니다. 두 벡터의 내적은 24×4+(−8)×32=−160입니다. 누산기 스케일은 2^8이므로 실제 값은 −160/256=−0.625이고, F=4 출력 정수는 −10입니다. 이 예는 나눗셈이 정확히 떨어집니다. 다음 예가 출력 정책의 차이를 드러냅니다.

음수에서 반올림을 시험하기

S=−17, F=4이면 정확한 출력 정수는 −1.0625입니다. 산술 오른쪽 시프트는 −2, 0 방향 절삭은 −1, 최근접 짝수 반올림도 −1을 만듭니다. 따라서 >>>를 쓴 코드를 단순히 '소수부 버리기'라고 설명하지 않습니다. 양수에서는 두 절삭이 같아도 음수에서는 다릅니다. S=−24이면 −1.5로 정확히 중간이며, 최근접 짝수는 −2를 선택합니다. S=−40이면 −2.5이므로 −2를 선택합니다.

이 과정의 기본 출력 계약은 전체 누산 후 최근접 짝수 반올림, 그다음 출력 폭으로 포화입니다. 절댓값에 대해 몫 q와 나머지 r을 구하고, r이 절반보다 크거나 절반이며 q가 홀수일 때 q를 하나 늘린 뒤 원래 부호를 붙이면 됩니다. 반올림에서 최솟값의 절댓값을 같은 폭 signed에 저장하면 오버플로가 날 수 있으므로 변환 함수에는 한 비트 이상의 여유를 둡니다. Node 참조는 BigInt를 사용해 그 문제를 피합니다.

출력 범위 밖의 값

8비트 signed 출력 범위는 −128..127입니다. 반올림 결과가 130이라면 포화는 127, 랩어라운드는 −126입니다. 결과가 −130이라면 포화는 −128, 랩어라운드는 126입니다. 포화는 정확한 값을 보존하지 않지만 큰 양수 결과가 음수로 뒤집히는 것을 막습니다. 랩어라운드가 필요한 설계도 있으므로 정책을 이름과 예제로 명시하는 것이 핵심입니다.

원시 누산 SF최근접 짝수8비트 포화
−1604−10−10
−174−1−1
−244−2−2
−404−2−2
20804130127

검증은 누산기 원시 값과 변환된 출력 두 지점에서 수행합니다. 원시 합이 틀리면 MAC 또는 스케줄 문제이고, 원시 합이 맞는데 출력만 다르면 스케일·반올림·포화 문제입니다. RTL과 참조 모델이 같은 잘못된 변환 함수를 공유하지 않도록 손으로 계산한 중간값을 시험에 고정합니다. 여기서는 정수형 MAC을 설계하며 부동소수점, 양자화 zero-point 또는 비대칭 스케일은 별도의 계약이 필요합니다.

직접 생각해 보기

F=4, S=−56의 최근접 짝수 출력 정수와, F=4, S=−2080의 8비트 포화 출력을 구하세요.

해설 보기

−56/16=−3.5이므로 짝수 −4를 선택합니다. −2080/16=−130이고 8비트 최솟값보다 작으므로 −128로 포화합니다. 변환 순서는 반올림 후 포화입니다.

선택은 이 브라우저에만 적용됩니다. 언제든 푸터에서 변경할 수 있습니다.