big.Int
타입과 관련된 타입과 유틸리티 함수들이 정의되어 있습니다.
- 어떤 수를 커다란 2의 제곱수에서 빼서 얻은 2진수를 2의 보수라고 합니다.
- 2의 보수를 사용하는 이유는 음수를 부호가 없는 정수(unsigned integer)로 표현하기 위해서입니다.
- 이 때 부호가 없는 정수는 이더리움에서 사용하는 256비트 uint256 타입의 정수입니다.
// U256은 큰 정수를 256비트 2의 보수 숫자로 인코딩합니다. 이 연산은 파괴적(원본값을 변경)입니다.
func U256(x *big.Int) *big.Int {
// x가 양수인 경우: x & tt256m1 -> x 자기 자신을 반환
// x가 음수인 경우: (2**256 - 1) & (-x) = (2**256 - 1) &^ (x - 1) -> x의 2의 보수를 반환 (여기서 x - 1은 양수 x의 모든 비트를 반전시킨 값)
// 빼기 연산을 사용하지 않은 이유: x가 양수인 경우 2**256 - x는 완전히 다른 값이 되므로
return x.And(x, tt256m1)
}
// S256은 2의 보수 x를 부호가 있는 256비트 숫자로 인코딩합니다.
// x는 256비트를 초과해서는 안됩니다(그렇게 되면 결과는 정의되지 않음).
// 이 연산은 파괴적(원본값을 변경)이지 않습니다.
//
// S256(0) = 0
// S256(1) = 1
// S256(2**255) = -2**255
// S256(2**256-1) = -1
func S256(x *big.Int) *big.Int {
if x.Cmp(tt255) < 0 { // x < 2**255 (왜 2**255보다 작으면 양수로 취급하는가?)
return x
}
return new(big.Int).Sub(x, tt256) // x - 2**256
}
- 정수와 관련된 타입과 도우미 함수들이 정의되어 있습니다.