FirmGod

진법 변환기

고정 폭으로 16진수·2진수·10진수를 변환하고, 부호 있는 해석과 바이트 순서, 비트 단위 조작까지 한 화면에서 확인합니다.

Range 0 to 4294967295

접두사와 구분자는 무시합니다.

Try:

비트

Click any bit to flip it. Numbering starts at bit 0 on the right.

bits 31–24
bits 23–16
bits 15–8
bits 7–0
Set bits: 24 of 32Positions: 31, 30, 28, 27, 26, 25, 23, 21, 19, 18, 16, 15, 13, 12, 11, 10, 9, 7, 6, 5, 3, 2, 1, 0

메모리상의 바이트

The same value as a little-endian machine and a big-endian one lay it out. Reading a buffer with the wrong order is what turns a sensible number into nonsense.

순서바이트ASCII값으로 읽으면
빅 엔디언DE AD BE EF····0xDEADBEEF
리틀 엔디언EF BE AD DE····0xEFBEADDE
Replaces the value with its byte-reversed form, for when a capture came off the wire the other way round.

모든 표현

16진수0xDEADBEEF
Hex, byte groupedDE AD BE EF
10진수3735928559
Signed reading-559038737
2진수1101 1110 1010 1101 1011 1110 1110 1111
8진수33653337357
C 리터럴0xDEADBEEFUL

직접 손으로 변환하기

계산은 위 도구가 바로 해 주지만, 산술 자체를 알아 두는 편이 낫습니다. 오실로스코프 화면이나 로그에 찍힌 값은 붙여 넣을 곳이 없고, 무엇보다 계산을 알아야 틀린 답을 알아봅니다.

2진수 → 10진수

오른쪽 끝을 0번으로 두고 각 자리는 2의 거듭제곱입니다. 비트가 켜진 자리의 값을 더하면 됩니다. 1011_0110이면 1·2·4·5·7번이 켜져 있으니 2 + 4 + 16 + 32 + 128 = 182입니다. 한 바이트라면 니블 둘로 끊어 각각을 16진수 한 자리로 읽는 쪽이 빠릅니다 — 1011은 11, 0110은 6이므로 0xB6, 즉 11 × 16 + 6 = 182입니다.

10진수 → 16진수

16으로 나누고 나머지를 뒤에서부터 적습니다. 182 ÷ 16은 몫 11 나머지 6, 11 ÷ 16은 몫 0 나머지 11이므로 자리는 11과 6, 곧 0xB6입니다. 한 바이트에 들어가는 값이면 2진수를 거치는 편이 보통 더 빠릅니다. 여덟 비트를 적고 니블로 끊어 각각을 한 자리로 읽으면 됩니다.

16진수 → ASCII

0x20부터 0x7E까지가 출력 가능한 ASCII 문자이고 한 바이트가 한 글자입니다. 48 65 6C 6C 6F는 Hello입니다. 0x20 미만은 문자가 아니라 제어 코드입니다 — 0x0A는 줄바꿈, 0x0D는 캐리지 리턴, 0x00은 C 문자열을 끝내는 종료 문자입니다. 도구가 그 자리에 점을 찍는 것은 없는 글자를 지어내지 않기 위해서입니다. 0x7F를 넘는 바이트는 ASCII가 아니며, 그 값이 무엇을 뜻하는지는 바이트 자체에 들어 있지 않은 인코딩이 정합니다.

이 변환기가 일반적인 진법 변환기와 다른 부분은 그 아래 전부입니다. 값의 폭이 몇 비트인지, 부호가 있는지를 먼저 묻습니다. 임베디드에서는 그 두 가지가 답을 바꾸기 때문입니다.

같은 비트, 다른 값

메모리에 들어 있는 것은 비트뿐입니다. 그 비트를 어떻게 읽을지는 코드가 정합니다. 0xFF라는 한 바이트는 부호 없는 정수로 읽으면 255이고, 2의 보수 부호 있는 정수로 읽으면 −1이며, 문자로 읽으면 또 다른 것이 됩니다.

디버거가 보여 주는 값과 코드가 계산한 값이 다를 때, 대부분은 이 해석의 차이입니다. 그래서 이 변환기는 하나를 고르게 하지 않고 부호 있는 해석과 없는 해석을 나란히 보여 줍니다.

폭이 먼저입니다

부호 있는 해석은 최상위 비트가 어디인지 알아야 성립합니다. 0xFF는 8비트에서 −1이지만 16비트에서는 그냥 255입니다. 앞에 0이 여덟 개 더 붙어 최상위 비트가 0이 되기 때문입니다.

그래서 변환하기 전에 폭을 먼저 정해야 합니다. 레지스터가 16비트면 16비트로, int32_t 변수면 32비트로 두어야 화면의 숫자가 코드 안의 값과 같아집니다.

2의 보수가 하는 일

음수를 표현하는 방법은 여럿이지만 현대 프로세서는 거의 모두 2의 보수를 씁니다. 부호 비트를 따로 두는 방식과 달리 0이 하나뿐이고, 덧셈 회로 하나로 뺄셈까지 처리할 수 있다는 것이 이유입니다.

그 대가로 범위가 비대칭입니다. 부호 있는 8비트는 −128부터 127까지입니다. 음수 쪽이 하나 더 많은데, abs(-128)이 8비트 안에서 표현되지 않는다는 뜻이기도 합니다. 절댓값을 취하는 코드가 최솟값에서 오버플로하는 버그가 여기서 나옵니다.

바이트 순서

한 바이트를 넘어가면 순서 문제가 생깁니다. 32비트 값 0x12345678을 메모리에 저장할 때 리틀 엔디언은 78 56 34 12로, 빅 엔디언은 12 34 56 78로 씁니다.

산업용 프로토콜에서는 여기에 중간 형태가 더해집니다. 16비트 워드 안의 바이트 순서와 워드끼리의 순서를 따로 뒤집을 수 있어 네 가지 조합이 나오고, 장비 문서가 어느 것인지 명확히 적지 않는 경우도 많습니다. 모드버스 레지스터에서 읽은 값이라면 모드버스 레지스터 디코더가 네 순서를 한 번에 보여 줍니다.

비트를 직접 만지는 쪽이 빠를 때

레지스터의 특정 비트를 세우거나 지웠을 때 값이 얼마가 되는지는 머릿속으로 계산할 수 있지만, 여러 개를 동시에 바꿔야 하면 실수하기 쉽습니다. 이 변환기는 표시된 비트를 눌러 바로 뒤집을 수 있고, 모든 표현이 같이 갱신됩니다.

설정 레지스터의 값을 데이터시트를 보며 조립할 때, 비트 필드마다 시프트와 마스크를 계산하는 것보다 눌러서 확인하는 편이 빠르고 틀릴 여지도 적습니다.

선행 0과 폭 표시

0xF와 0x0F는 같은 값이지만 코드 리뷰에서는 다른 의미를 전달합니다. 폭에 맞춰 자릿수를 채워 적으면 그 값이 몇 비트짜리 대상인지가 드러나고, 마스크나 비교 상수를 읽을 때 실수를 줄여 줍니다.

이 변환기는 선택한 폭에 맞춰 자릿수를 채워 표시합니다. 복사해서 코드에 붙일 때 그대로 쓸 수 있는 형태입니다.

자주 묻는 질문

2진수를 10진수로 어떻게 바꾸나요?

오른쪽 끝을 0번 자리로 두고, 비트가 켜진 자리의 2의 거듭제곱을 더합니다. 1011_0110은 1·2·4·5·7번이 켜져 있으므로 2 + 4 + 16 + 32 + 128 = 182입니다. 한 바이트라면 니블 둘로 끊어 각각을 16진수 한 자리로 읽는 쪽이 빠릅니다. 1011은 B, 0110은 6이니 0xB6이고 11 × 16 + 6 = 182입니다.

10진수를 16진수로 어떻게 바꾸나요?

16으로 나누고 나머지를 뒤에서부터 적습니다. 182 ÷ 16은 몫 11 나머지 6, 11 ÷ 16은 몫 0 나머지 11이므로 자리는 11과 6, 곧 0xB6입니다. 한 바이트에 들어가는 값이면 2진수를 거치는 편이 더 빠릅니다. 여덟 비트를 적고 니블로 끊어 각각을 한 자리로 읽으면 됩니다.

0xFF가 255인가요 −1인가요?

둘 다입니다. 비트 패턴은 하나지만 해석이 두 가지입니다. 부호 없는 8비트로 읽으면 255, 2의 보수 부호 있는 8비트로 읽으면 −1입니다. 어느 쪽인지는 비트가 결정하지 않고 코드의 타입이 결정합니다. 그래서 이 변환기는 두 해석을 동시에 보여 줍니다.

폭을 왜 먼저 정해야 하나요?

폭이 없으면 부호 있는 해석이 성립하지 않습니다. 0xFF는 8비트에서 −1이지만 16비트에서는 255입니다. 최상위 비트가 어디인지가 부호를 정하기 때문입니다. 레지스터나 변수의 실제 폭을 넣어야 의미 있는 값이 나옵니다.

바이트 순서는 언제 신경 써야 하나요?

메모리나 회선에서 읽은 여러 바이트를 하나의 수로 합칠 때입니다. 같은 32비트 값이라도 리틀 엔디언 장비는 하위 바이트를 먼저 저장하고 빅 엔디언 장비는 반대입니다. 산업용 프로토콜에서는 16비트 단위로만 뒤집는 중간 형태도 흔해서, 네 가지 조합을 모두 확인해야 하는 경우가 많습니다.

비트를 직접 눌러 바꿀 수 있나요?

가능합니다. 표시된 비트를 클릭하면 그 자리만 뒤집히고 모든 표현이 함께 갱신됩니다. 레지스터의 특정 플래그를 세우거나 지웠을 때 값이 어떻게 되는지 확인할 때 계산하는 것보다 빠릅니다.

음수를 16진수로 바꾸면 어떻게 되나요?

2의 보수로 변환됩니다. 8비트에서 −1은 0xFF, −128은 0x80입니다. 폭을 넘어서는 값은 표현할 수 없으므로 범위를 벗어났다고 알려 줍니다. 부호 있는 8비트는 −128에서 127까지만 담을 수 있습니다.