16진수 변환기

16진수·10진수·2진수를 실시간 상호 변환

출발/목표 진법을 위에서 고르고, 값을 입력하면 자동으로 변환됩니다.

16진수 변환기 소개

이 도구는 16진수·10진수·2진수 중 하나를 입력하면 나머지 둘로 바꿔 보여 줍니다. 내부에서 JavaScript의 BigInt를 쓰기 때문에 자릿수 제한이 없습니다. 64비트 해시나 128비트 UUID를 통째로 넣어도 끝자리가 뭉개지지 않습니다.

기본 설정(비트 폭 「제한 없음」)에서는 부호 없는 정수로 다루므로 FF는 255입니다. 그런데 디버거나 메모리 덤프에서 FF를 보면 -1인 경우가 많습니다. 비트 폭을 8·16·32·64 중에서 고르고 「부호 있는 값(2의 보수)」을 켜면 FF를 -1로 읽고, 10진수 칸에 -5 같은 음수도 넣을 수 있습니다. 아래에서는 같은 비트 묶음이 왜 255도 되고 -1도 되는지 설명합니다. 소수점은 어느 모드에서도 받지 않습니다.

0xFF가 -1이 되는 이유: 2의 보수

컴퓨터 메모리에는 부호가 따로 저장되지 않습니다. 8비트 칸에 11111111이 있을 뿐이고, 그것을 부호 없는 수(uint8)로 읽으면 255, 부호 있는 수(int8)로 읽으면 -1입니다. 거의 모든 현대 CPU는 부호 있는 정수를 2의 보수로 표현합니다. 규칙은 간단합니다. n비트에서 최상위 비트가 1이면 부호 없는 값에서 2^n을 뺀 것이 실제 값입니다.

8비트라면 0xFF = 255 - 256 = -1, 0x80 = 128 - 256 = -128, 0x7F = 127입니다. 그래서 int8의 범위는 -128~127로 음수 쪽이 하나 더 깁니다. 반대로 -5를 8비트 16진수로 나타내려면 비트 폭 8, 부호 있는 값을 켜고 10진수 -5를 넣으면 됩니다(부호 없는 모드라면 256 - 5 = 251을 넣어도 같습니다). 결과는 FB, 2진수로 11111011입니다.

2의 보수가 쓰이는 이유는 덧셈 회로 하나로 뺄셈까지 처리할 수 있어서입니다. 11111111(-1)에 00000001을 더하면 1_00000000이 되고, 8비트 밖으로 넘친 자리는 버려지므로 0이 됩니다. 부호 비트를 따로 두는 방식이나 1의 보수에서는 +0과 -0이 둘 다 생기는데, 2의 보수에는 0이 하나뿐입니다.

비트 폭을 모르면 해석할 수 없다

FF가 -1인지는 그 값이 몇 비트 칸에 들어 있었는지에 달려 있습니다. 16비트 칸의 0x00FF는 그냥 255이고, 16비트에서 -1은 0xFFFF입니다. 32비트면 0xFFFFFFFF, 64비트면 F가 16개입니다. 즉 「앞자리 F가 몇 개인가」보다 「최상위 비트가 비트 폭의 맨 앞에 있는가」가 기준입니다.

비트 폭이 「제한 없음」이면 앞의 0을 지우고 출력하므로 0x00FF를 넣으면 FF가 나옵니다. 비트 폭을 고르면 출력이 그 폭에 맞게 0으로 채워지고(16비트에서 FF → 00FF), 폭을 넘는 값은 범위 초과로 알려 줍니다.

  • 8비트(byte, int8/uint8): 00~FF, 부호 있으면 -128~127
  • 16비트(short): 0000~FFFF, 부호 있으면 -32,768~32,767
  • 32비트(int): 부호 있는 최댓값 0x7FFFFFFF = 2,147,483,647
  • 64비트(long): 부호 있는 최댓값 0x7FFFFFFFFFFFFFFF = 9,223,372,036,854,775,807

16진수가 널리 쓰이는 이유

16 = 2^4이라서 16진수 한 자리가 정확히 2진수 네 자리(니블)에 대응합니다. 그래서 1바이트는 항상 16진수 두 자리이고, 2진수를 네 자리씩 끊어 읽기만 하면 머릿속에서 바꿀 수 있습니다. 10진수는 이런 대응이 없어 255와 256 사이에서 자릿수가 바뀌어도 비트 경계와 무관합니다. 색상 코드 #RRGGBB, MAC 주소, 메모리 주소, UTF-8 바이트가 모두 16진수로 적히는 이유가 이것입니다.

C 계열 언어의 0x 접두어, 2진수의 0b 접두어는 이 도구에서도 받아들입니다. 공백은 무시되므로 「DE AD BE EF」처럼 바이트 단위로 띄워 쓴 값도 그대로 넣을 수 있습니다. 대소문자는 구분하지 않고, 결과 16진수는 대문자로 나옵니다.

예시

메모리 덤프의 FB를 부호 있는 8비트로 읽기

입력
16진수 FB
결과
10진수 251, 2진수 11111011

최상위 비트가 1이므로 int8로는 251 - 256 = -5입니다. uint8로 읽는다면 251 그대로입니다.

32비트 부호 있는 정수의 최댓값

입력
10진수 2147483647
결과
16진수 7FFFFFFF, 2진수 1이 31개

여기에 1을 더한 80000000은 int32에서 -2,147,483,648로 넘어갑니다. 정수 오버플로가 음수로 뒤집히는 모습입니다.

공백 섞인 바이트열

입력
16진수 DE AD BE EF
결과
10진수 3735928559

공백은 무시됩니다. 0xDEADBEEF는 초기화되지 않은 메모리를 표시하는 값으로 오래 쓰여 온 관용 표기입니다. int32로 읽으면 3735928559 - 4294967296 = -559038737입니다.

사용 방법

  1. 16진수·10진수·2진수 중 입력할 칸을 고릅니다.
  2. 값을 넣습니다. 0x, 0b 접두어와 공백은 있어도 됩니다. 부호 있는 정수로 읽으려면 비트 폭을 고르고 「부호 있는 값」을 켭니다.
  3. 나머지 두 진법 결과를 확인하고 복사합니다.

자주 묻는 질문

음수를 넣을 수 있나요?

비트 폭(8·16·32·64)을 고르고 「부호 있는 값(2의 보수)」을 켜면 10진수 칸에 음수를 넣을 수 있습니다. 16비트에서 -1을 넣으면 FFFF, 8비트에서 -129처럼 범위를 벗어나면 범위 초과로 표시됩니다. 64비트도 BigInt로 계산해 정확합니다.

아주 큰 수도 정확한가요?

BigInt로 계산하므로 자릿수 제한 없이 정확합니다. 일반 숫자(배정밀도)는 2^53을 넘으면 끝자리가 틀리는데, 이 도구에서는 그런 문제가 없습니다.

소수(0.5 같은 값)는 변환되나요?

안 됩니다. 정수만 지원합니다. 부동소수점 수의 비트 패턴은 IEEE 754 형식이라 단순 진법 변환과는 다른 계산이 필요합니다.

결과 앞의 0이 사라졌어요.

비트 폭이 「제한 없음」이면 값만 보여 주므로 앞자리 0이 생략됩니다. 비트 폭을 고르면 16진수와 2진수가 그 폭에 맞게 0으로 채워집니다.

출처

기준일:

개인정보와 저장 방식