IEEE 754 부동소수점 변환기
10진수 부동소수점을 IEEE 754 2진수·16진수로 변환하는 온라인 도구. FP16/32/64·bfloat16 지원, 실제 저장 값·반올림 오차·비트 레이아웃을 브라우저에서 확인합니다.
| 부호 | |
| 지수부 | |
| 가수부 |
- 입력한 값
- 실제 저장 값
- 반올림 오차
- 이전
- 다음
- ULP (간격 크기)
| 형식 | 총 비트 수 | 부호 | 지수부 | 가수부 | 바이어스 | 최대 유한 값 | 10진 자릿수 |
|---|---|---|---|---|---|---|---|
| binary16 (FP16) | 16 | 1 | 5 | 10 | 15 | 65504 | ~3.3 |
| bfloat16 | 16 | 1 | 8 | 7 | 127 | ≈3.39×10³⁸ | ~2.3 |
| binary32 (FP32) | 32 | 1 | 8 | 23 | 127 | ≈3.40×10³⁸ | ~7.2 |
| binary64 (FP64) | 64 | 1 | 11 | 52 | 1023 | ≈1.80×10³⁰⁸ | ~15.9 |
IEEE 754 부동소수점이란?
IEEE 754는 컴퓨터가 실수를 2진수로 저장하는 방식을 정의하는 표준입니다. 모든 값은 세 필드에 담깁니다: 부호 비트, 지수부(큰 크기와 아주 작은 크기를 모두 표현할 수 있도록 바이어스를 더해 저장), 그리고 유효 자릿수를 담는 가수부입니다. 거의 모든 CPU, GPU, 프로그래밍 언어가 이 표준을 사용하므로 JavaScript, Python, C, SQL에서 똑같은 반올림 문제가 나타납니다.
핵심 통찰은 2진 부동소수점이 m × 2ⁿ 형태의 수만 표현할 수 있다는 점입니다. 0.1 같은 10진 소수는 2진법에서 무한 순환 소수 — 0.000110011001100… — 이므로, 형식은 대신 가장 가까운 표현 가능한 이웃 값을 저장합니다. 단정밀도에서 그 이웃은 0.100000001490116119384765625이고, 배정밀도에서는 0.1000000000000000055511151231257827021181583404541015625입니다. 둘 다 0.1이 아닙니다. 그 뒤에 따라오는 모든 기이한 현상 — 0.1 + 0.2 ≠ 0.3, 조금씩 어긋나는 합계, 실패하는 동등성 검사 — 은 이 하나의 사실에서 비롯되며, 이 변환기는 반올림된 근사치가 아니라 정확한 저장 값을 출력해 이를 눈에 보이게 만듭니다.
표준은 특수 값을 위한 비트 패턴도 예약해 둡니다. 지수부가 모두 1이면 ±Infinity(가수부 0) 또는 NaN(가수부 0이 아님)을 인코딩하고, 지수부가 모두 0이면 부호 있는 0(가수부 0) 또는 서브노멀 수(가수부 0이 아님)를 인코딩합니다. 서브노멀 수는 0 옆의 언더플로 구간을 낮은 정밀도로 메웁니다. 이 도구가 다루는 네 형식 — binary16/FP16, bfloat16, binary32/FP32, binary64/FP64 — 은 각 필드에 배정하는 비트 수만 다릅니다: 지수 비트가 많을수록 범위가 넓어지고 가수 비트가 많을수록 정밀도가 높아집니다. 머신러닝이 애용하는 bfloat16은 단순히 FP32에서 하위 16개 가수 비트를 잘라낸 것입니다: 범위는 같고 정밀도는 훨씬 거칩니다.
유용한 사고 모델은, 표현 가능한 부동소수점이 수직선 위에 격자를 이루며 그 간격 — 마지막 자리의 한 단위, 즉 ULP — 이 2의 거듭제곱마다 두 배가 된다는 것입니다. 1.0 근처에서 double의 격자 간격은 약 2.22 × 10⁻¹⁶이지만, 2⁵³ 근처에서는 정수 하나에 이릅니다. double이 2⁵³을 넘어서는 정수를 신뢰할 수 있게 세지 못하는 이유입니다. 이 도구의 이웃 값 패널은 그 격자를 직접 보여줍니다: 입력한 값 주변의 이전·다음 표현 가능한 값과 둘 사이의 정확한 간격입니다.
// Float ↔ hex through the raw IEEE 754 bits (works in any browser / Node.js)
const buf = new DataView(new ArrayBuffer(8));
function floatToHex32(value) {
buf.setFloat32(0, value); // rounds to nearest even
return '0x' + buf.getUint32(0).toString(16).toUpperCase().padStart(8, '0');
}
function hexToFloat32(hex) {
buf.setUint32(0, parseInt(hex, 16));
return buf.getFloat32(0);
}
floatToHex32(0.1); // '0x3DCCCCCD'
floatToHex32(3.14159); // '0x40490FD0'
hexToFloat32('3DCCCCCD'); // 0.10000000149011612 주요 기능
네 가지 형식, 하나의 화면
반정밀도(FP16), bfloat16, 단정밀도(FP32), 배정밀도(FP64) — 클릭 한 번으로 전환하면 페이지 전체가 다시 계산되므로, 같은 숫자가 각 형식에서 어떻게 저장되는지 몇 초 만에 비교할 수 있습니다.
클릭 가능한 비트 그리드
모든 비트가 버튼입니다. 부호를 반전하고 지수부를 조정하고 가수 비트를 눌러 보면 10진수·16진수·2진수 표시가 즉시 갱신됩니다 — 인코딩에 대한 직관을 기르는 가장 빠른 방법입니다.
근사치가 아닌 정확한 저장 값
이 도구는 정확한 큰 정수 연산으로 저장된 비트의 전체 10진 전개를 계산합니다 — double의 0.1이라면 55자리 전부 — 그리고 입력한 값 대비 부호 있는 정확한 반올림 오차도 함께 보여줍니다.
이웃 값과 ULP
현재 숫자 주변의 이전·다음 표현 가능한 값과 둘 사이의 정확한 간격(ULP)을 확인하세요 — 어떤 크기에서 실제로 얼마나 정밀한지를 결정하는 격자 간격입니다.
특수 값을 클릭 한 번으로
칩을 누르면 선택한 형식의 ±0, ±Infinity, NaN, 최소 서브노멀, 최대 유한 값이 로드되고, 분류 배지가 현재 비트 패턴이 무엇을 인코딩하는지 알려줍니다.
공유 가능한 퍼머링크, 업로드 없음
링크 복사는 형식과 정확한 비트 패턴을 URL에 인코딩합니다 — 버그 리포트, 코드 리뷰, 강의 자료에 이상적입니다. 모든 것이 브라우저에서 실행되며 입력한 내용은 페이지를 벗어나지 않습니다.
IEEE 754 변환 예시
단정밀도의 0.1 — 고전적인 반올림 오차
0.1
0x3DCCCCCD — 실제로는 0.100000001490116119384765625로 저장됨
10진수 0.1은 유한한 2진수 표현이 없으므로 IEEE 754는 가장 가까운 표현 가능한 값을 대신 저장합니다. 단정밀도(FP32)에서 그 값은 0x3DCCCCCD이며, 정확히 0.100000001490116119384765625 — 약 1.49 × 10⁻⁹만큼 더 큰 값입니다. 이 도구는 프로그래밍 언어가 반올림해 출력하는 '0.1'이 아니라, 실제 저장된 값과 정확한 오차를 자릿수 하나까지 보여줍니다. 이 예시 하나가 0.1 + 0.2가 0.3과 같지 않은 이유를 포함해 부동소수점의 의외의 동작 대부분을 설명합니다.
Float to Hex: FP32의 3.14159
3.14159
0x40490FD0
단정밀도(FP32)를 선택한 상태에서 3.14159를 입력하면 hex 필드에 0x40490FD0이 표시됩니다 — 부호 0, 바이어스 적용 지수 128(즉 2¹), 가수부 0x490FD0. 실제로 저장되는 값은 3.141590118408203125로, 입력한 값보다 아주 약간 큽니다. 16진수 형식은 네트워크 덤프, GPU 버퍼, 레지스터 뷰, 직렬화된 바이너리 파일에서 만나게 되는 형태이며, 변환은 양방향으로 동작합니다: 40490FD0을 hex 필드에 붙여넣으면 다시 10진수로 디코딩됩니다.
FP16 최댓값: 반정밀도의 한계는 65504
65504
0x7BFF — 가장 큰 유한 FP16 값
반정밀도는 지수 비트 5개와 가수 비트 10개뿐이므로 가장 큰 유한 값은 65504(0x7BFF)입니다. 65520이나 그보다 큰 값을 입력하면 결과가 Infinity(0x7C00)로 반올림됩니다 — 머신러닝 모델을 FP16으로 양자화할 때 실제로 마주치는 위험입니다. bfloat16으로 전환하면 같은 65520도 여유 있게 들어가는데, bfloat16이 가수 비트(정밀도)를 포기하는 대신 FP32의 지수 비트 8개(범위)를 유지하기 때문입니다. 바로 이 트레이드오프가 ML 학습이 bfloat16을, 소형 저장이 FP16을 선호하는 이유입니다.
−0과 +0: 서로 다른 두 비트 패턴, 하나의 값
-0
0x80000000 (FP32), +0은 0x00000000
IEEE 754에는 부호 있는 0이 있습니다: −0은 부호 비트만 1이고(FP32에서 0x80000000) +0은 모든 비트가 0입니다. 어떤 언어에서든 둘은 같다고 비교되지만 1/−0은 −Infinity, 1/+0은 +Infinity이므로 차이가 관찰 가능합니다. 도구에서 부호 비트를 클릭해 둘 사이를 오가면 분류 배지가 0에 머무는 동안 16진수 값만 바뀌는 것을 볼 수 있습니다 — 비트 수준의 동일성과 수치상의 동일성이 다른 개념임을 클릭 한 번으로 보여주는 예시입니다.
IEEE 754 부동소수점 변환 방법
- 1
부동소수점 형식 선택
단정밀도(FP32)가 기본으로 선택되어 있습니다. JavaScript/Python 스타일 숫자에는 배정밀도(FP64)로, 머신러닝과 그래픽스에서 쓰이는 16비트 형식에는 반정밀도(FP16)나 bfloat16으로 전환하세요.
- 2
10진수 입력
0.1, -2.5e3, 65504 등 어떤 값이든 입력하거나 ±0, ±Infinity, NaN, 최소 서브노멀, 최대 유한 값 특수 값 칩을 사용하세요. 입력과 동시에 변환이 이루어집니다.
- 3
색상으로 구분된 비트 레이아웃 읽기
부호 비트, 지수부 필드, 가수부가 서로 다른 색으로 강조되며, 필드 분해 표에는 원시 비트, 바이어스 계산, 암시적 선행 비트가 표시됩니다.
- 4
정확한 저장 값과 오차 확인
정확도 패널은 실제로 저장되는 값을 — 모든 자릿수를 정확하게 계산해 — 입력한 값 대비 반올림 오차와 함께 출력하고, 이전·다음 표현 가능한 이웃 값과 ULP 간격도 보여줍니다.
- 5
비트 반전, hex 붙여넣기, 결과 복사
아무 비트나 클릭해 반전하거나 16진수(3DCCCCCD)와 2진수 문자열을 붙여넣어 다시 10진수로 디코딩하세요. 16진수, 2진수, 정확한 값, 또는 동일한 비트 패턴을 재현하는 공유 링크를 복사할 수 있습니다.
흔한 부동소수점 실수
저장된 값 대신 출력된 값을 신뢰
언어는 부동소수점을 왕복 변환이 가능한 가장 짧은 문자열로 반올림해 출력하므로 0.1은 깔끔해 보이지만 저장된 값은 그렇지 않습니다. 정밀도는 print()가 보여주는 것이 아니라 정확한 전개로 판단하세요.
print(0.1) # 0.1 — 정확해 보이지만 아님
0.1 저장 값 (FP64) = 0.1000000000000000055511151231257827021181583404541015625
부동소수점을 정확한 동등성으로 비교
0.1 + 0.2는 비트 패턴 0x3FD3333333333334에 놓이고 리터럴 0.3은 0x3FD3333333333333입니다 — ULP 하나 차이이므로 둘 다 0.3 비슷하게 출력되어도 ==는 false입니다.
if (0.1 + 0.2 === 0.3) { … } // 절대 실행되지 않음 if (Math.abs(a - b) < 1e-9) { … } // 데이터 크기에 맞춘 허용 오차 범위 확인 없이 FP16으로 양자화
FP16의 가장 큰 유한 값은 65504입니다. 그보다 큰 값은 모두 Infinity가 되고, Infinity가 계산에 들어오면 그대로 전파됩니다. 하향 변환 전에 최댓값을 확인하세요 — 또는 FP32의 범위를 유지하는 bfloat16을 사용하세요.
fp16(65520) → Infinity (0x7C00) — 조용한 오버플로
bf16(65520) → 유한 값 (bfloat16은 지수 비트 8개 유지)
NaN을 동등성으로 검사
NaN은 자기 자신과도 같지 않은 유일한 값입니다 — 실패한 계산이 정상 숫자로 위장할 수 없도록 의도된 설계입니다. == 대신 언어의 isNaN 검사를 사용하고, 서로 다른 NaN 비트 패턴이 수백만 개 존재한다는 점을 기억하세요.
if (x === NaN) { … } // x가 NaN이어도 항상 false if (Number.isNaN(x)) { … } // 올바른 검사 IEEE 754 변환기로 할 수 있는 일
- 직렬화된 바이너리 데이터 디버깅
- 네트워크 캡처, GPU 버퍼, 레지스터 덤프, 파일 형식에서 발견한 16진수를 붙여넣어 정확한 10진수 값으로 디코딩하거나, 반대 방향으로 변환해 테스트 픽스처를 작성하세요. 바이트 순서 참고: 표시되는 16진수는 빅 엔디언 비트 패턴입니다. 덤프가 리틀 엔디언이라면 붙여넣기 전에 바이트 순서를 반전하세요.
- ML 양자화 이해
- 값이 FP16의 65504 상한을 넘지 않는지 점검하고, FP16과 bfloat16의 정밀도 손실을 자릿수 단위로 비교하고, 그래디언트가 언더플로되는 서브노멀 구간을 살펴보세요.
- 부동소수점 버그 설명
- 동료가 '같은' 두 숫자가 왜 다른지 물으면 두 비트 패턴과 정확한 저장 값을 보여주는 퍼머링크를 보내세요 — 논쟁이 저절로 정리됩니다. 긴 덤프에는 텍스트 비교 도구를 함께 사용하세요.
- 인코딩 학습과 교육
- 학생이 지수 비트를 직접 클릭하고 바이어스 계산이 갱신되는 것을 보면 컴퓨터 구조 수업이 구체적으로 다가옵니다. 필드 분해 표는 교과서가 형식을 그리는 방식을 그대로 반영합니다.
- 임베디드·산업용 레지스터 디코딩
- Modbus, CAN, 센서 페이로드는 FP32 값을 원시 16진수 워드로 전달하는 경우가 많습니다. 여기에 워드를 붙여넣으면 임시 스크립트를 작성하지 않고도 물리량을 읽을 수 있습니다.
IEEE 754 형식과 특수 값
- 네 가지 2진 형식 한눈에 보기
- binary16(FP16): 부호 1 + 지수 5 + 가수 10비트, 바이어스 15, 최대 65504, 10진 약 3.3자리. bfloat16: 1 + 8 + 7, 바이어스 127, 최대 ≈ 3.39 × 10³⁸, 약 2.3자리. binary32(FP32): 1 + 8 + 23, 바이어스 127, 최대 ≈ 3.40 × 10³⁸, 약 7.2자리. binary64(FP64): 1 + 11 + 52, 바이어스 1023, 최대 ≈ 1.80 × 10³⁰⁸, 약 15.9자리. 패턴은 이렇습니다: 지수 비트는 범위를, 가수 비트는 정밀도를 사고, bfloat16은 FP32의 범위를 얻기 위해 정밀도를 의도적으로 모두 내놓습니다.
- 값이 조립되는 방식
- 정규 수는 (−1)^부호 × 1.가수부 × 2^(지수 − 바이어스)로 디코딩됩니다. 선행 1은 암시적이어서 저장되지 않으며, 23비트 가수부 필드가 24비트 정밀도를 제공하는 이유입니다. 저장되는 지수는 실제 지수에 바이어스(FP32에서 127)를 더한 값이므로 2⁰은 01111111로 저장됩니다. 이 도구의 필드 분해 표는 현재 값에 대해 그 계산의 각 단계를 보여줍니다.
- 특수 값: 예약된 지수 패턴
- 지수부가 모두 1이고 가수부가 0이면 ±Infinity, 가수부가 0이 아니면 NaN입니다(표준적인 quiet NaN은 가수부 최상위 비트를 1로 설정). 지수부가 모두 0이고 가수부가 0이면 ±0, 가수부가 0이 아니면 서브노멀이며 0.가수부 × 2^(1 − 바이어스)로 디코딩됩니다 — 암시적 선행 1이 없습니다. 이 규칙은 네 형식 모두에서 동일하며, 같은 칩이 모든 형식에서 동작하는 이유입니다.
- 반올림: 가장 가까운 값으로, 동률이면 짝수로
- 값이 두 표현 가능한 수 사이에 놓이면 IEEE 754의 기본 모드는 더 가까운 쪽으로 반올림하고, 정확히 중간이면 마지막 가수 비트가 0인 쪽(짝수 방향)을 선택해 체계적인 쏠림을 방지합니다. 이 변환기는 10진수 입력을 대상 형식으로 좁힐 때 정확히 이 규칙을 적용하며, 오차 패널은 그 결과로 생기는 부호 있는 차이를 정확하게 표시합니다.
- ULP: 부동소수점의 격자 간격
- 표현 가능한 부동소수점은 고르게 퍼져 있지 않습니다 — 이웃 사이의 간격(마지막 자리의 한 단위)은 2의 거듭제곱마다 두 배가 됩니다. 1.0 근처에서 double의 ULP는 2⁻⁵² ≈ 2.22 × 10⁻¹⁶이고, 2⁵³ 근처에서는 ULP가 1.0에 도달해 정수를 건너뛰기 시작합니다. 이웃 값 패널은 현재 ULP를 정확히 출력하며, '내 숫자가 여기서 얼마나 정밀한가?'에 대한 정직한 답입니다.
부동소수점 모범 사례
- 부동소수점을 ==로 비교하지 말 것
- 어떤 연산이든 거친 뒤에는 수학적으로 같은 두 식이 ULP 하나 차이로 벌어질 수 있습니다. 값의 크기에 맞는 허용 오차와 비교하거나, 비트 패턴 사이의 ULP 수를 세세요 — 이 도구에서 직접 확인할 수 있습니다.
- 금액은 2진 부동소수점에 넣지 말 것
- 어떤 2의 거듭제곱 격자도 0.10을 정확히 담지 못하므로, float에 담긴 통화는 눈에 보이는 오차를 누적합니다. 정수 센트나 decimal 타입을 사용하세요. 이 도구의 정확한 저장 값 패널이 그 이유를 보여주는 상시 증거입니다.
- 16비트 형식은 습관이 아니라 범위로 선택
- 값이 65504를 넘을 수 있다면 — 손실 함수, 그래디언트, 물리 시뮬레이션의 급증 — FP16은 Infinity로 오버플로되지만 bfloat16은 아무 일 없이 지나갑니다. 모든 값이 좁은 대역으로 정규화되어 있다면 FP16의 추가 가수 비트가 눈에 띄게 나은 정밀도를 제공합니다.
- 좁히기 변환의 이중 반올림 함정 주의
- 드문 중간값 사례에서 10진수 → double → half 변환은 10진수 → half 직접 변환과 ULP 하나 차이가 날 수 있습니다. 이 도구는 10진수 입력을 대상 형식으로 한 번에 반올림하므로, 화면에 보이는 값이 정직한 IEEE 754 답입니다.
- 2⁵³ 이상에서는 정수가 깨진다고 예상할 것
- double은 2⁵³까지의 모든 정수를 정확히 저장한 뒤 건너뛰기 시작합니다 — 2⁵³ + 1은 표현할 수 없습니다. 그 규모의 ID나 카운터를 다룬다면 64비트 정수나 문자열을 사용하고, 의심스러운 값은 여기서 비트 수준으로 점검하세요.
IEEE 754 변환기 자주 묻는 질문
0.1 + 0.2는 왜 0.3과 같지 않나요?
IEEE 754란 무엇인가요?
FP16과 bfloat16의 차이는 무엇인가요?
서브노멀(비정규) 수란 무엇인가요?
float와 double 중 무엇을 써야 하나요?
부동소수점을 손으로 16진수로 변환하려면 어떻게 하나요?
이 변환기를 사용할 때 데이터가 업로드되나요?
관련 도구
모든 도구 보기 →진법 변환기 (Number Base Converter)
변환 도구
2진수, 16진수, 10진수, 8진수 및 임의 진법(2-36)을 즉시 변환합니다. 온라인에서 무료로 사용할 수 있으며 모든 처리는 브라우저에서 이루어집니다.
색상 변환기 — HEX, RGB, HSL, OKLCH
변환 도구
HEX, RGB, HSL, OKLCH, OKLAB, CMYK 등 9가지 색상 형식을 브라우저에서 즉시 변환합니다. 무료 온라인 도구, 가입 불필요.
HEX CMYK 변환기
변환 도구
HEX 색상을 CMYK로 변환합니다. 인쇄 시안용 sRGB 기반 근사. 무료 온라인 도구, 색상은 페이지를 벗어나지 않습니다.
HEX HSL 변환기
변환 도구
HEX 색상을 HSL로 변환합니다. 3자리, 6자리, 알파 포함 8자리 모두 지원. 무료 온라인 도구, 즉시 변환.
HEX OKLCH 변환기
변환 도구
HEX를 Tailwind v4 디자인 토큰용 OKLCH로 변환합니다. 지각적으로 균일한 실시간 출력과 Display P3 색역 경고. 무료, 브라우저 전용.
HEX RGB 변환기
변환 도구
HEX 색상 코드를 RGB로 변환합니다. 3자리, 6자리, 알파 포함 8자리 모두 지원. 무료 온라인 도구, 즉시 변환.