IEEE-754 플로트 시각화 장치
십진수가 IEEE-754 부동 소수점(부호 비트, 지수 비트, 가수 비트)으로 어떻게 저장되는지, 그리고 0.1과 같은 숫자가 정확히 저장되지 않는 이유를 정확히 알아보세요.
결과
컴퓨터에 저장되는 모든 부동 소수점 숫자(JavaScript 숫자, C 부동 소수점, Python 부동 소수점)는 IEEE 754에서 동일한 방식으로 부호 비트 1개, 지수 비트 블록, 가수(분수) 비트 블록으로 인코딩됩니다. 단정밀도(32비트)는 부호 비트 1개, 지수 비트 8개, 가수 비트 23개를 사용합니다. 거의 모든 언어의 기본 숫자 유형 뒤에 있는 형식인 배정밀도(64비트)는 1개의 부호 비트, 11개의 지수 비트 및 52개의 가수 비트를 사용합니다. 이 도구는 사용자가 입력한 모든 십진수를 가져와 브라우저의 자체 DataView/ArrayBuffer 부동 소수점 인코더(코드가 실제로 실행되는 것과 동일한 기계)를 사용하여 두 너비 중 하나로 인코딩하고 해당 숫자가 속한 지역에 따라 각 비트에 색상을 지정합니다.
인코딩 자체는 세 단계를 따르며, 이 도구는 최종 비트만 표시하는 대신 모든 단계를 안내합니다. 첫째, 정규화: 숫자는 1.mantissa × 2^지수로 다시 작성됩니다. 이진수 앞에 0이 아닌 숫자가 정확히 하나 있습니다(숫자가 너무 작으면 암묵적인 선행 1 없이 비정규 처리를 받습니다). 둘째, 지수 편향: 지수 필드는 양수와 음수 지수를 모두 부호 없는 숫자로 저장해야 하므로 필드가 이진수로 기록되기 전에 고정 편향(단정밀도의 경우 127, 배정밀도의 경우 1023)이 추가됩니다. 셋째, 소수 가수는 전통적인 "2를 곱하고 정수 부분을 다음 비트로 취하고 나머지를 유지하는" 방법을 사용하여 비트 단위로 확장됩니다. 가수 필드가 가득 찰 때까지 반복되며, 이 시점에서 남은 비트는 결과를 반올림할지 내림할지 결정합니다(반올림에서 짝수로, IEEE-754 기본값).
이것이 바로 0.1과 같은 평범한 숫자가 정확하게 저장되지 않는 이유입니다. 이진수에서 0.1은 반복되는 분수(0.0001100110011…, 영원히)이므로 유한한 가수는 이를 정확하게 보유할 수 없습니다. 어딘가에서 반올림해야 합니다. 0.1을 32비트 부동 소수점으로 인코딩하고 비트를 다시 읽으면 0.1을 다시 얻지 못합니다. 정확히 0.100000001490116119384765625를 얻습니다. 배정밀도에는 작업할 가수 비트가 29개 더 있으므로 반올림 오류는 훨씬 작지만 0도 아닙니다. 64비트 배정밀도는 정확히 0.1000000000000000055511151231257827021181583404541015625이므로 0.1입니다. 이 도구는 큰 정수 산술(부동 소수점 단축키 없음)을 사용하여 정확한 저장된 값을 계산하므로 사용자가 입력한 내용과 하드웨어가 실제로 유지하는 내용 사이의 차이가 숨겨지거나 근사화되지 않습니다.
특수 값은 일반 인코딩이 아닌 정확하고 예약된 비트 패턴을 가져옵니다. 0과 음수 0에는 모두 0인 지수 및 가수 비트가 있고(부호 비트만 다름) ±Infinity에는 모두 0인 가수가 있는 모두 1개의 지수 비트가 있고, NaN에는 최소 1개의 가수 비트가 설정된 모두 1개의 지수 비트가 있습니다. 여기에 있는 모든 내용은 브라우저에서 로컬로 실행됩니다. 입력한 내용은 어디에도 업로드되지 않습니다. 따라서 이곳은 부동 소수점 버그에 대한 실제 직관을 구축할 수 있는 안전한 장소입니다. 거의 모든 프로그래밍 언어에서 '0.1 + 0.2 !== 0.3'인 이유, 그래픽 코드의 float32 텍스처가 float64가 그렇지 않은 정밀도를 잃는 이유, 금융 코드에서 일반적으로 바이너리 부동 소수점을 모두 피해야 하는 이유.