04구현 문제
잘못된 정수 리터럴 네 개 진단하기
1. 현재 값부터 계산하기
리터럴을 고치기 전에 각 오른쪽 식이 실제로 나타내는 수치와 폭을 계산해 보세요.
literalConstant의 지역 선언 네 개는 문법 오류가 없어 컴파일되지만, 반환값은 요구된
계약과 다릅니다. 원인은 각각 잘못된 10진 값, 진법 변환 없이 옮긴 8진 숫자, 일부만 남은
값을 확장한 16진 식, 최하위 비트만 1인 정수입니다.
selector별 반환 계약은 다음과 같습니다.
selector | 반환 조건 |
|---|---|
| 0 | 수치 42 |
| 1 | 수치 42 |
| 2 | 수치 48879 |
| 3 | 16개 비트가 모두 1 |
수정 범위는 네 지역 선언의 오른쪽 식입니다. case와 mkTop은 그대로 두세요.
2. 증상과 원인 구분하기
starter를 실행해 현재 값 네 개를 확인해 보세요. 출력 행에는 잘못된 결과만 나타나므로, 고칠 리터럴은 직접 계산해서 찾아야 합니다.
8진 선언은 각 자릿값을 8의 거듭제곱으로 계산합니다. 10진 표기의 숫자를 그대로 옮기면
같은 수치가 되지 않습니다. 16진 선언은 안쪽 리터럴의 폭부터 읽어 보세요. zeroExtend는
상위에 0을 추가할 뿐, 좁은 값에서 이미 빠진 상위 비트를 복원하지 않습니다. 마지막 선언의
수치 1은 최하위 비트 하나만 1로 만들므로 폭 전체를 채운 값과 다릅니다.
3. 반환 계약 복구하기
각 오류 원인에 맞춰 오른쪽 식 네 개를 최소한으로 바꾸세요. 10진, 8진, 16진, 그리고 문맥에서 폭을 얻는 채움 리터럴의 관계를 설명할 수 있어야 합니다. 단, 컴파일 결과에는 리터럴의 진법 표기가 남지 않습니다. 서로 다른 식이 같은 16비트 값을 만들면 반환 동작만으로는 표기를 구분할 수 없습니다.
수정한 뒤 네 selector를 모두 실행해 다음을 확인하세요.
selector0과 1은 진법이 달라도 같은 수치 42를 반환합니다.selector2는 상위 비트를 잃지 않고 48879를 반환합니다.selector3은 최하위 비트뿐 아니라 16개 비트가 모두 1입니다.case분기와mkTop의 구조는 바뀌지 않습니다.
두 리터럴이 진법은 다른데 같은 값을 반환하는 이유와, 채움 리터럴이 Bit#(16)에서 폭을
얻는 과정을 직접 설명해 보세요.
4. 단계형 단서
단서 1
크기 지정 리터럴은 폭, 진법 문자, 숫자 순서로 읽습니다. 같은 숫자 문자열도 진법이 달라지면 각 자릿값이 달라집니다.
단서 2
먼저 목표 수치를 모두 담을 수 있는 폭을 정하세요. 좁은 리터럴을 확장하는 연산은 없는 상위 비트를 복원하지 않습니다.
단서 3
채움 리터럴은 자체 폭이 없고, 대입되는 Bit#(16) 문맥에서 폭을 얻습니다. 정수 1과
모든 비트가 1인 값을 구분하세요.
5. 다른 폭에 적용하기
임시 코드에서 대입 대상의 타입을 Bit#(8)로 바꾼다고 가정해 보세요. 네 목표 가운데
8비트 범위를 벗어나는 수치를 찾아보세요. 모든 비트를 1로 채우는 값이 폭을 따로 적지
않아도 새 폭에 맞춰지는지 실행 전에 계산해 보세요.