51검증 문제
부호 있는 값의 비트 보존하기
1. 문제와 수정 범위
mkSignedAdapter.encode는 Int#(32)를 받아 signedCarrier(value)를
foreignSignedBits에 넘깁니다. 이 외부 함수 선언은 부호 없는 32비트 carrier를 씁니다.
C 쪽이 부호를 직접 해석하려면 값의 2의 보수 비트 패턴 전체를 받아야 합니다. 그런데
수정할 수 있는 signedCarrier가 0을 반환하므로 공개 실행은 -7에 대해
carrier = 00000000을 출력합니다.
signedCarrier의 본문만 수정하세요. Int#(32) 입력 타입, Bit#(32) 반환 타입, adapter,
외부 함수 선언, mkTop은 그대로 둡니다.
2. starter 읽기와 실행 전 예측
signedCarrier의 본문보다 타입을 먼저 읽어 보세요. 입력 타입에는 부호 의미가 있고, 반환 타입은 폭이 같은 비트 벡터입니다.- 결과가
foreignSignedBits로 가는 경로를 따라가 보세요. 기본 실행에서는 같은 시그니처로 인자를 그대로 반환하는 BSV 대역 함수가 쓰이므로, C 경계를 넘을 값이 그대로 출력됩니다. - 실행 전에
-7의 32비트 2의 보수 패턴을 16진수로 적어 보세요. starter의 출력과 고친 뒤의 출력을 예측해 보세요.
3. 최소 수정과 완료 조건
이 변환은 계산이 아니라 표현의 변경입니다. 부호 반전, 절댓값, 확장은 필요하지 않습니다. 두 타입이 모두 32비트이므로 모든 비트가 그대로 carrier에 도착해야 합니다. 반환 식만 바꾼 뒤 다시 실행하고, carrier 타입에 부호가 없는데도 부호 비트가 남는 이유를 설명해 보세요.
- 모든
Int#(32)값에서 carrier는 그 값을pack한 비트와 같습니다. - 음수, 0, 양수 모두 부호 비트를 포함한 모든 비트를 유지합니다.
- 함수 타입과 외부 함수 선언은 바뀌지 않습니다.
- 화면의
-7만 따로 처리하면 다른 입력에서 실패합니다.
4. 단계형 힌트
힌트 1: 의미와 비트 구분하기
C carrier에는 부호가 없지만 BSV 입력 타입에는 부호 의미가 남아 있습니다. 경계는 비트만 넘기고, 받는 쪽이 의미를 다시 붙입니다.
힌트 2: 쓸 변환
산술 연산 없이 타입 있는 값을 Bits 표현으로 변환하세요. 두 타입의 폭이 같으므로 폭
변환은 필요하지 않습니다.
5. 추가 실험
공개 입력을 바꾸기 전에 -1, 0, 1의 carrier를 예측해 보세요. 그중 하나로 입력을
바꾸어 실행한 뒤 -7로 되돌리세요. 부호 해석과 비트 전달이 어디서 나뉘는지 확인하는
실험입니다.