IEEE-754 Floating Point, Brain Float BF16 & Numerical Stability: Why 0.1 + 0.2 ≠ 0.3
How William Kahan packed 600 orders of magnitude into 64 bits, why 9007199254740992 + 1 loses the 1, and why AI hardware traded FP16 for BF16 and FP8.
Open Python, JavaScript, C, or Rust and print '0.1 + 0.2': back comes '0.30000000000000004'! Far from a software bug, this is the inescapable geometry of squeezing the infinite real number line into 64 finite silicon switches. William Kahan's 1985 IEEE-754 standard encodes numbers in base-2 scientific notation (−1)^s × (1.fraction)_2 × 2^(E − bias), packing subatomic 10⁻³⁰⁸ scales and cosmic 10³⁰⁸ scales into one register by spacing representable ticks logarithmically — razor-dense near zero, yet 2.0 apart above 2⁵³ = 9,007,199,254,740,992! Understanding where bits live — exponent dynamic range vs. mantissa precision — explains why banks never store dollars in binary floats, why Google's 16-bit 'Brain Float' (BF16) unlocked modern LLM training without gradient overflow, and why subtracting 'max(x)' saves every Transformer softmax layer from 'NaN' collapse.
- 1.Prime-Factor Trap (0.1 + 0.2 ≠ 0.3): Because 1/10 = 1/(2 × 5) has prime factor 5 outside base 2, 0.1 repeats infinitely in binary (0.000110011₂...); rounding 0.1 and 0.2 to 53 bits rounds both slightly up, exceeding 0.3_fl by 2⁻⁵⁴ ≈ 5.55 × 10⁻¹⁷.
- 2.IEEE-754 Bit Layout & 2⁵³ Safe-Integer Ceiling: Hidden leading '1.' gives FP64 1 sign + 11 exponent + 52 stored mantissa = 53 bits precision (~15.95 digits); above 2⁵³ = 9,007,199,254,740,992, tick spacing hits 2.0, while NaN obeys NaN ≠ NaN.
- 3.AI's BF16 & FP8 Hardware Shift: IEEE FP16 (5 exponent bits, max 65,504) overflows LLM gradients; Brain Float BF16 (1 sign + 8 exponent + 7 mantissa) keeps full FP32 range (±3.4 × 10³⁸) at half memory & ~4× smaller multiplier silicon, joined by E4M3/E5M2 FP8.
- 4.Non-Associativity, Kahan Summation & Safe Softmax: '(a + b) + c ≠ a + (b + c)' makes parallel GPU sums order-dependent; Kahan summation recovers low-order bits, and 'exp(x_i − max(x))' prevents exp(89) overflow to ∞/∞ = NaN.
THE FIRST BIT — Build Binary Adders From Logic Gates
First-Principles Mechanism (Step by Step)
1. Base-2 Prime Arithmetic: Why 0.1 + 0.2 = 0.30000000000000004 Everywhere
In base 10, why is 1/8 = 0.125 exact and finite while 1/3 = 0.33333... repeats forever? A reduced fraction p / q terminates in base B if and only if every prime factor of denominator q also divides B! Base 10 has prime factors 2 and 5; binary base 2 has ONLY prime factor 2. Consequently, 1/10 = 1 / (2 × 5) is haunted by that factor of 5: multiplying repeatedly by 2 turns decimal 0.1 into the endlessly repeating binary string 0.00011001100110011₂...! Inside a 64-bit IEEE-754 'double' (53-bit significand), hardware must chop that infinite tail using 'round-to-nearest, ties-to-even'. Both 0.1 (stored as ~0.10000000000000000555...) and 0.2 (stored as ~0.20000000000000001110...) happen to round slightly UPWARD, whereas 0.3 rounds slightly DOWNWARD (~0.29999999999999998890...). When your CPU adds rounded 0.1 + rounded 0.2, the two upward errors combine and tip rounding one Unit in the Last Place (1 ULP at exponent 2⁻² equals 0.25 × 2⁻⁵² = 2⁻⁵⁴ ≈ 5.55 × 10⁻¹⁷) above closest-representable 0.3 — printing '0.30000000000000004'! That is why financial databases, payment rails, and tax engines NEVER store money in binary floats: they store exact 64-bit integer cents/micro-units or base-10 decimal128!
2. Inside Kahan's IEEE-754: The Free Hidden Bit, 2⁵³ Gaps & Why NaN ≠ NaN
Before 1985, running identical Fortran physics code across IBM, DEC VAX, and Cray supercomputers produced conflicting answers or mid-flight crashes. Turing-Award mathematician William Kahan standardized IEEE-754 around base-2 scientific notation: (−1)^s × (1.m)_2 × 2^(E − bias). Notice Kahan's cleverest bit-saving trick: in binary, every normalized non-zero number starts with '1.' (never 2 through 9!), so hardware gets 1 extra bit of precision completely FREE without storing it! Thus 64-bit FP64 (1 sign + 11 exponent [bias 1023] + 52 stored mantissa) delivers 53 bits of precision (log₁₀(2⁵³) ≈ 15.95 decimal digits across ±1.8 × 10³⁰⁸), while 32-bit FP32 (1 + 8 [bias 127] + 23) delivers 24 bits (~7.22 digits). Because exponent scales step size, tick spacing doubles at every power of two: between 1 and 2, gaps equal ε = 2⁻⁵² ≈ 2.22 × 10⁻¹⁶; at 2⁵² they hit 1.0; and right at 2⁵³ = 9,007,199,254,740,992 (one above JavaScript's 'Number.MAX_SAFE_INTEGER'), gaps widen to 2.0 — so '9007199254740992 + 1' evaluates to '9007199254740992'! Kahan also dedicated E = 0 to 'subnormal' numbers (0.m × 2^(−1022)) for gradual underflow, and E = all-ones to ±∞ plus 'NaN' (0/0, ∞ − ∞), defining 'NaN == NaN' as FALSE so corrupted sensor pipelines can spot poison values via 'x != x'!
3. Why AI Silicon Ditched FP16 for Brain Float BF16, FP8 & Mixed Precision
Training frontier neural networks moves petabytes of weights, activations, and gradients across HBM memory buses where bandwidth costs far more energy than arithmetic! Cutting 32-bit FP32 in half to standard IEEE 16-bit 'FP16' (1 sign + 5 exponent + 10 mantissa) looked tempting — until LLM researchers hit constant 'NaN' explosions: FP16's 5-bit exponent overflows past 65,504 and flushes tiny attention gradients below ~6 × 10⁻⁸ to zero! Google Brain engineers realized deep learning doesn't need 10 bits of mantissa precision during stochastic training, because mini-batch gradient noise already dwarfs fine rounding — what neural nets desperately need is wide exponent dynamic range! Enter 'bfloat16' (BF16: 1 sign + 8 exponent + 7 mantissa): by preserving FP32's exact 8-bit exponent (±3.4 × 10³⁸ drop-in range, convertible from FP32 by simply slicing off the bottom 16 bits!), BF16 eliminates fragile loss-scaling hacks while shrinking silicon multiplier gate area roughly 4× (since multiplier complexity scales quadratically with mantissa width: 8² = 64 vs. FP16's 11² = 121 and FP32's 24² = 576)! Today's Hopper/Blackwell Tensor Cores go further still: 8-bit 'FP8' pairs E4M3 (4 exponent, 3 mantissa for forward weights/activations) with E5M2 (5 exponent, 2 mantissa for wider backward gradients), accumulating products inside wide FP32 registers!
4. Catastrophic Cancellation, Non-Associative GPUs & Safe Transformer Softmax
Floating-point arithmetic violates high-school algebra: '(a + b) + c' does NOT always equal 'a + (b + c)'! Compute '(10²⁰ + (−10²⁰)) + 1.0' and you get '0.0 + 1.0 = 1.0'; regroup it as '10²⁰ + ((−10²⁰) + 1.0)' and '−10²⁰ + 1.0' rounds straight to '−10²⁰', returning '0.0'! Because GPU parallel reductions sum thousands of partial thread blocks in non-deterministic arrival order, identical LLM prompts at temperature = 0 can drift slightly across batch sizes unless deterministic reduction trees are enforced! Even deadlier are two classic numerical landmines: first, 'Catastrophic Cancellation' occurs when subtracting two nearly equal rounded numbers (like −b + √(b² − 4ac) when 4ac ≪ b², or naive variance ∑x²/N − μ²), erasing all shared leading digits and amplifying rounding noise by 10¹⁰× — cured by algebraic rationalization, Welford's online variance, or William Kahan's 4-line 'compensated summation' (carrying lost low-order dust in a side variable 'c')! Second, inside every Transformer attention block, naive 'softmax(x)_i = exp(x_i) / ∑ exp(x_j)' explodes to '∞ / ∞ = NaN' whenever any FP32 logit exceeds 88.72 (because e⁸⁹ > 3.4 × 10³⁸)! Subtracting m = max(x) first — 'exp(x_i − m) / ∑ exp(x_j − m)' — leaves exact mathematical ratios unchanged while clamping the largest exponent at exp(0) = 1.0!
Common Myths vs. Verified Reality (Audited by SkepticJudge)
Why does '0.1 + 0.2' differ from '0.3' in IEEE-754 binary64, and why did AI hardware architects choose 'bfloat16' (BF16) over standard IEEE 'FP16' for training large neural networks?
Verified Primary Lectures & Sources (90+ Brain-Score)
Browse All 10,534 Sources →How Floating-Point Numbers Are Represented
- • Unlike fixed-point binary, IEEE 754 floating-point preserves dynamic range by storing a sign bit, exponent, and mantissa.
- • Single-precision 32-bit floats subtract a 127 bias from an 8-bit exponent and omit the leading 1 for 24-bit mantissa precision.
Why do computers suck at math?
- • 64-bit floating-point numbers dynamically shift the radix point to trade finite bit precision against wide numerical range.
- • Standard 64-bit floats preserve up to 15 accurate integer digits and roughly 17 decimal places in Python and JavaScript.
Give me 30 min, I will make Quantization click forever
- • Outlier weights stretch per-tensor scale factors and ruin precision, requiring finer per-channel or group-wise quantization.
- • Because silicon addresses memory in 8-bit bytes, INT4 inference packs two 4-bit integers into each byte via bitwise shifts.
Quantizing LLMs - How & Why (8-Bit, 4-Bit, GGUF & More)
- • IEEE 754 floats store sign, biased exponent, and mantissa; mapping FP16 weights to INT8 or 4-bit cuts LLM VRAM demands by up to 80%.
- • BitsAndBytes quantizes Hugging Face SafeTensors into 8-bit or NF4 packed representations for consumer GPUs with minimal perplexity loss.
Tippt man in Python, JavaScript, C oder Rust ‚0.1 + 0.2‘ ein, antwortet der Rechner mit ‚0.30000000000000004‘! Das ist kein Programmierfehler, sondern reine Zahlentheorie beim Versuch, das unendliche Kontinuum der reellen Zahlen in 64 endliche Transistor-Bits zu falten. William Kahans IEEE-754-Standard (1985) speichert Zahlen in binärer Exponentialdarstellung (−1)^s × (1.Mantisse)_2 × 2^(E − Bias): nahe null liegen die darstellbaren Zahlen extrem dicht beieinander, verdoppeln ihren Abstand jedoch mit jeder Zweierpotenz — bis oberhalb von 2⁵³ = 9.007.199.254.740.992 die Lücken auf 2,0 anwachsen und ‚+ 1‘ wirkungslos verpufft! Wer versteht, wie sich Bits auf Exponenten-Dynamikumfang und Mantissen-Präzision verteilen, durchschaut sofort, warum Finanzsysteme Cent-Beträge niemals als Binär-Float speichern, warum Googles ‚Brain Float‘ (BF16) das Training moderner Sprachmodelle revolutionierte und warum ‚exp(x − max(x))‘ jede Transformer-Schicht vor dem ‚NaN‘-Absturz rettet.
- 1.Primfaktor-Falle (0,1 + 0,2 ≠ 0,3): Da 1/10 = 1/(2 × 5) den zur Basis 2 teilerfremden Primfaktor 5 enthält, ist 0,1 binär periodisch (0,000110011₂...); 53-Bit-Rundung rundet 0,1 und 0,2 leicht auf, sodass ihre Summe 0,3_fl um 2⁻⁵⁴ ≈ 5,55 × 10⁻¹⁷ übertrifft.
- 2.IEEE-754-Architektur & 2⁵³-Ganzzahlgrenze: Durch das implizite führende ‚1.‘-Bit bietet FP64 (1 + 11 + 52) volle 53 Bit Präzision (~15,95 Dezimalstellen); ab 2⁵³ = 9.007.199.254.740.992 beträgt die Schrittweite 2,0, und für NaN gilt per Standard NaN ≠ NaN.
- 3.Warum KI-Hardware BF16 & FP8 nutzt: Klassisches FP16 (5 Exponenten-Bits, Maximum 65.504) läuft bei KI-Gradienten ständig über; BF16 (1 + 8 + 7) behält den vollen FP32-Wertebereich (±3,4 × 10³⁸) bei halbem Speicherbedarf und ~4× kleineren Rechenwerken.
- 4.Nicht-Assoziativität, Kahan-Summe & stabiles Softmax: Wegen ‚(a + b) + c ≠ a + (b + c)‘ hängen parallele GPU-Summen von der Reihenfolge ab; Kahan-Summation rettet Rundungsreste, und ‚exp(x_i − max(x))‘ verhindert ∞/∞ = NaN im Transformer-Attention-Block.
THE FIRST BIT — Binär-Addierer selbst aus Gattern verdrahten
Wie es Schritt für Schritt wirklich funktioniert
1. Primzahlen im Binärsystem: Warum überall 0,1 + 0,2 = 0,30000000000000004 gilt
Warum bricht im Zehnersystem 1/8 = 0,125 exakt ab, während 1/3 = 0,33333... endlos weiterläuft? Ein gekürzter Bruch p / q endet in einer Zahlenbasis B genau dann nach endlich vielen Stellen, wenn sämtliche Primfaktoren des Nenners q auch Teiler von B sind! Unsere Alltagsbasis 10 besitzt die Primfaktoren 2 und 5 — die Computerbasis 2 jedoch NUR den Primfaktor 2. Darum scheitert ausgerechnet der harmlose Dezimalbruch 1/10 = 1 / (2 × 5) am Primfaktor 5: Binär ausgeschrieben wird 0,1 zum unendlich periodischen Bruch 0,00011001100110011₂...! Ein 64-Bit-IEEE-754-Float (‚binary64‘) muss diese Kette nach 53 signifikanten Bits per ‚Round-to-Nearest-Even‘ kappen. Zufällig werden dabei sowohl 0,1 (~0,10000000000000000555...) als auch 0,2 (~0,20000000000000001110...) minimal AUFGERUNDET, während 0,3 minimal ABGERUNDET wird (~0,29999999999999998890...). Addiert die CPU das aufgerundete 0,1 und 0,2, summieren sich beide Aufrundungsfehler und schieben das Ergebnis um exakt 1 ULP (im Intervall [0,25; 0,5) gilt 0,25 × 2⁻⁵² = 2⁻⁵⁴ ≈ 5,55 × 10⁻¹⁷) über den besten 0,3-Näherungswert hinaus zu ‚0.30000000000000004‘! Deshalb speichern Banken, Börsen und Buchhaltungen Geldbeträge NIEMALS als Binär-Float, sondern als exakte 64-Bit-Integer-Cents oder im Basis-10-Dezimalformat!
2. Kahans IEEE-754-Meisterwerk: Das Gratis-Bit, die 2⁵³-Mauer & warum NaN ≠ NaN gilt
Vor 1985 lieferte identischer Physik-Code auf Rechnern von IBM, DEC und Cray unterschiedliche Ergebnisse oder stürzte bei Unterlauf plötzlich ab. Turing-Preisträger William Kahan vereinte die Welt mit IEEE-754 auf die binäre Normalform (−1)^s × (1.m)_2 × 2^(E − Bias). Kahans eleganter Trick: Im Binärsystem beginnt jede normierte Zahl ungleich null zwingend mit ‚1.‘ — diese führende Eins muss gar nicht gespeichert werden und schenkt ein volles Präzisions-Bit gratis! So erreicht 64-Bit-FP64 (1 Vorzeichen + 11 Exponent [Bias 1023] + 52 Mantisse) echte 53 Bit Signifikandenschärfe (log₁₀(2⁵³) ≈ 15,95 Dezimalstellen über ±1,8 × 10³⁰⁸), 32-Bit-FP32 (1 + 8 [Bias 127] + 23) solide 24 Bit (~7,22 Stellen). Da der Abstand benachbarter Floats mit jeder Zweierpotenz aufs Doppelte wächst, beträgt die Lücke zwischen 1 und 2 winzige 2⁻⁵² ≈ 2,22 × 10⁻¹⁶, bei 2⁵² exakt 1,0 — und ab 2⁵³ = 9.007.199.254.740.992 (knapp über ‚Number.MAX_SAFE_INTEGER‘) volle 2,0: ‚9007199254740992 + 1‘ rundet wieder zurück auf ‚9007199254740992‘! Überdies schuf Kahan mit E = 0 ‚subnormale‘ Zahlen gegen abrupten Null-Absturz sowie mit E = alle-Einsen ±∞ und ‚NaN‘ (z. B. 0/0), für das per Definition ‚NaN == NaN‘ immer FALSCH liefert!
3. Warum KI-Beschleuniger FP16 durch Brain Float BF16 und FP8 ersetzten
Beim Training großer KI-Sprachmodelle ist nicht das bloße Rechnen der Flaschenhals, sondern die Speicherbandbreite zwischen HBM-Stapelspeicher und Chip! Die Halbierung von 32-Bit-FP32 auf das klassische IEEE-Halbformat ‚FP16‘ (1 Vorzeichen + 5 Exponent + 10 Mantisse) führte jedoch im Training zu ständigen ‚NaN‘-Abbrüchen: Mit nur 5 Exponenten-Bits läuft FP16 schon oberhalb von 65.504 nach Unendlich über, während feine Gradienten unterhalb von ~6 × 10⁻⁸ zu null verschwinden! Ingenieure bei Google Brain erkannten den wahren Bedarf neuronaler Netze: Stochastisches Rauschen verzeiht grobe Mantissenrundung mühelos, solange niemals der Exponenten-Dynamikumfang reißt! Deshalb behielt ‚bfloat16‘ (BF16: 1 Vorzeichen + 8 Exponent + 7 Mantisse) exakt die 8 Exponenten-Bits von FP32 (±3,4 × 10³⁸ Wertebereich — Umwandlung aus FP32 durch simples Abschneiden der hinteren 16 Bit!) bei halbem Speicherbedarf und rund vierfach kleinerer Chipfläche für Multiplizierer (deren Gatterzahl quadratisch mit der Mantissenbreite schrumpft: 8² = 64 statt 24² = 576 bei FP32)! Moderne Tensor-Cores kombinieren inzwischen sogar zwei 8-Bit-Formate (‚FP8‘): E4M3 für präzise Gewichte/Aktivierungen im Vorwärtspfad und E5M2 für breit gestreute Gradienten im Rückwärtspfad — stets aufsummiert in sicheren 32-Bit-FP32-Akkumulatoren!
4. Auslöschung, nicht-assoziative GPUs & der Softmax-Rettungstrick
Auf realer Hardware gilt das Assoziativgesetz der Schulmathematik NICHT mehr: ‚(a + b) + c‘ ist im Allgemeinen ungleich ‚a + (b + c)‘! Rechnet man ‚(10²⁰ + (−10²⁰)) + 1,0‘, erhält man exakt ‚1,0‘; klammert man dagegen ‚10²⁰ + ((−10²⁰) + 1,0)‘, verschluckt ‚−10²⁰ + 1,0‘ die winzige Eins spurlos und liefert am Ende ‚0,0‘! Da parallele GPU-Kernel Teilblöcke oft in leicht wechselnder Reihenfolge aufaddieren, können selbst KI-Modelle bei Temperatur 0 minimal schwanken, sofern keine deterministische Baumreduktion erzwungen wird! Zwei weitere Numerik-Fallen lauern in jedem Code: Erstens vernichtet ‚katastrophale Auslöschung‘ beim Subtrahieren zweier fast gleicher Zahlen (etwa −b + √(b² − 4ac) für kleines 4ac oder naive Varianz ∑x²/N − μ²) alle führenden gültigen Ziffern und zieht bloßes Rundungsrauschen nach vorn — geheilt durch Umformung, Welfords Online-Varianz oder Kahans ‚kompensierte Summation‘, die verlorene Niederbit-Reste in einer Korrekturvariablen mitschleppt! Zweitens sprengt in jedem Transformer-Netz ein naives ‚exp(x_i) / ∑ exp(x_j)‘ ab x_i > 88,72 sofort FP32 zu ‚∞ / ∞ = NaN‘: Erst der Kniff ‚exp(x_i − max(x)) / ∑ exp(x_j − max(x))‘ kürzt mathematisch exakt e^(−max) heraus und deckelt das größte Glied unverwüstlich auf exp(0) = 1,0!
Häufige Irrtümer vs. geprüfte Realität (SkepticJudge)
Warum weicht ‚0.1 + 0.2‘ in IEEE-754-Binary64 von ‚0.3‘ ab, und warum bevorzugen KI-Chips beim Training großer neuronaler Netze ‚bfloat16‘ (BF16) gegenüber klassischem ‚FP16‘?
Geprüfte Primär-Vorträge im DeepScroll-Index
Alle 10.534 Quellen →How Floating-Point Numbers Are Represented
- • Anders als Festkommazahlen bewahrt IEEE-754-Gleitkomma den Dynamikbereich durch Vorzeichenbit, Exponent und Mantisse.
- • 32-Bit-Floats ziehen vom 8-Bit-Exponenten den Bias 127 ab und sparen die führende 1 für effektiv 24 Bit Mantissenpräzision.
Why do computers suck at math?
- • 64-Bit-Gleitkommazahlen verschieben das Komma dynamisch, um endliche Bit-Präzision gegen großen Wertebereich abzuwägen.
- • Standard-64-Bit-Floats bieten bis zu 15 exakte Ganzzahlstellen und maximal 17 Nachkommastellen in Python und JavaScript.
Give me 30 min, I will make Quantization click forever
- • Ausreißer-Gewichte verzerren globale Skalierungsfaktoren und erfordern feinere Per-Channel- oder Group-Wise-Quantisierung.
- • Da Hardware Speicher byteweise (8 Bit) adressiert, packt INT4-Inferenz zwei 4-Bit-Werte per Bit-Shifting in ein einziges Byte.
Quantizing LLMs - How & Why (8-Bit, 4-Bit, GGUF & More)
- • IEEE-754-Floats speichern Vorzeichen, Exponent und Mantisse; INT8- oder 4-Bit-Quantisierung senkt den LLM-VRAM-Bedarf um bis zu 80 %.
- • BitsAndBytes komprimiert SafeTensors-Gewichte in 8-Bit- oder gepackte NF4-Formate für Consumer-GPUs bei minimalem Qualitätsverlust.
Connected AI-Wiki Articles
Built with specialist AI agents, allied research bots & learner support to keep humanity's knowledge 100% ad-free forever.