Fundamentals 12 min read

Why JavaScript Float Addition Is Inaccurate: Inside V8’s Machine Code

This article explains how the V8 JavaScript engine generates machine code for floating‑point addition on Intel x64, covering V8’s architecture, the IEEE‑754 representation that causes precision loss, and a step‑by‑step analysis of the relevant C++ source and the resulting addsd instruction.

Weidian Tech Team
Weidian Tech Team
Weidian Tech Team
Why JavaScript Float Addition Is Inaccurate: Inside V8’s Machine Code

Abstract

This article introduces how the V8 engine generates machine code for floating‑point addition on the Intel x64 platform. It first gives a brief overview of V8, then explains why floating‑point addition results are inaccurate from C and x64 assembly perspectives, and finally examines the V8 source code that produces the corresponding machine code.

V8 Overview

V8 is Google’s open‑source high‑performance JavaScript and WebAssembly engine written in C++. It powers Chrome, Node.js, and many other applications, running on Windows, macOS, and Linux across x64, IA‑32, ARM, and MIPS architectures. The source tree contains many directories; the core JavaScript‑related code resides in the

src

folder.

The compilation pipeline is: the parser converts JavaScript to an AST (in

src/parsing

and

src/ast

), the interpreter generates bytecode (

src/interpreter

), and the optimizing compiler later translates hot bytecode into machine code (

src/compiler

and

src/codegen

).

Why JavaScript Float Operations Are Inaccurate

Floating‑point numbers follow the IEEE‑754 double‑precision format (64 bits: 1 sign bit, 11 exponent bits, 52 mantissa bits). Because the mantissa is limited, adding numbers with vastly different exponents can lose low‑order bits, causing results like

a == d

to be true even though mathematically

a < d

.

<code>#include &lt;stdio.h&gt;
#include &lt;math.h&gt;
int main() {
    double a = pow(2, 100);
    double b = pow(2, 47);
    double c = pow(2, 48);
    double d = a + b;
    double e = a + c;
    printf("a == d is %d\n", a == d);
    printf("a == e is %d\n", a == e);
}
</code>

On x86, the exponent alignment shifts the smaller operand, and the extra mantissa bit is discarded, leading to the observed equality.

How V8 Generates Float‑Addition Machine Code

On x64, the floating‑point addition instruction is

addsd

(or

vaddsd

). V8 emits this instruction via the

Assembler::addsd

method, which writes the opcode bytes

0xF2 0x0F 0x58

and then calls

emit_sse_operand

to produce the ModR/M byte

0xC8

for

addsd xmm1, xmm0

.

<code>void Assembler::addsd(XMMRegister dst, XMMRegister src) {
    EnsureSpace ensure_space(this);
    emit(0xF2);
    emit_optional_rex_32(dst, src);
    emit(0x0F);
    emit(0x58);
    emit_sse_operand(dst, src);
}
</code>

The

emit_sse_operand

method constructs the final byte by combining the high bits

0xC0

with the low‑order bits of the destination and source registers:

<code>void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
    emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
}
</code>

For

dst = xmm1

(code 1) and

src = xmm0

(code 0), the calculation yields

0xC0 | 0x08 | 0x00 = 0xC8

, completing the four‑byte machine code

F2 0F 58 C8

for the addition.

Conclusion

The V8 engine translates JavaScript floating‑point addition into the

addsd

instruction by emitting the exact opcode bytes defined by the Intel manual. Understanding this process clarifies why floating‑point precision issues arise and how V8’s code generator implements the operation at the machine‑code level.

JavaScriptcompilerV8Machine Codex86floating-point
Weidian Tech Team
Written by

Weidian Tech Team

The Weidian Technology Platform is an open hub for consolidating technical knowledge. Guided by a spirit of sharing, we publish diverse tech insights and experiences to grow and look ahead together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.