ToolConvoyToolConvoyv2.6

int vs float: How Numbers Are Stored

An int stores whole numbers exactly but only in a finite range. A float stores a much wider range but with rounding errors. Most bugs come from mixing them.

Advertisement

int vs float: How Numbers Are Stored

int (integer) and float (floating-point) are two ways a programming language represents a number, and the choice has consequences you’ll feel as soon as your code touches real data.

An int is exact and countable: 42 is 42, no rounding, no surprise. A float is approximate and continuous: 0.1 + 0.2 is 0.30000000000000004 in IEEE 754 double precision, which surprises everyone the first time they meet it.

The exact range

An int is finite. In most modern systems, an int32 holds 2^32 distinct values (−2,147,483,648 to 2,147,483,647). A int64 holds 2^64. Beyond that, the type literally cannot represent the number any more.

A float is roughly continuous. An IEEE 754 float64 (a “double” in C-derived languages) can represent numbers from about 10^−308 to 10^308, with about 15-17 significant decimal digits. The catch: not every number in that range is representable exactly. Many values (like 0.1) get rounded.

Why 0.1 + 0.2 ≠ 0.3

In binary floating-point, 0.1 is not a clean fraction. Just as 1/3 in decimal becomes 0.3333…, 1/10 in binary becomes 0.000110011001100… repeating. The float has to round to a finite number of bits, and the actual stored value is slightly off.

When you add two rounded numbers, the rounding errors accumulate. 0.1 + 0.2 becomes slightly more than 0.3, and the float prints as 0.30000000000000004.

This is not a bug. It’s IEEE 754 working correctly. The bug is using float for things that should be exact.

Which to use

Use int when:

  • You’re counting things (rows, indices, sizes)
  • You’re storing money in cents (or satoshis, or wei — always integer minor units)
  • You’re dealing with IDs, dates stored as seconds/ms, byte counts
  • You need exact equality (a == b to mean what you’d expect)

Use float when:

  • You’re computing physical quantities (distances, weights, angles)
  • You’re aggregating sums where exactness is less important than range
  • You’re doing math that benefits from a wide range (scientific, graphics)
  • You accept that comparisons need a tolerance (abs(a - b) < epsilon)

The mixing trap

Most subtle bugs come from mixing int and float. In a dynamically typed language:

  • 5 / 2 — integer division in many languages, gives 2; in JavaScript, gives 2.5
  • 5.0 / 2 — in any language, gives 2.5
  • int(2.5) and Math.floor(2.5) — both give 2 in most languages; JavaScript surprises you when int doesn’t exist

Integers wider than int64 (very large IDs, high-precision timestamps, blockchain amounts) need special types: Python’s int is arbitrary precision; C++ has __int128 and libraries like boost::multiprecision; JavaScript numbers are always float64 (use BigInt for integers beyond 2^53).

Currency and the canonical lesson

Most financial bugs in 50 years of computing come from storing currency as float. The fix is universal: store money in its smallest integer unit (cents, pence, satoshis). 1999 cents is 19.99 dollars, never approximated. Conversion to a human-readable number happens only at display time, using a library that does decimal arithmetic (or careful integer division with rounding rules).

Tools

For working with numbers embedded in JSON or CSV data — where you may encounter ints that look like floats or floats that look like ints — the JSON to CSV and JSON to YAML converters round-trip values faithfully without changing their type.

For SQL, where int vs float column choices affect every downstream query, the SQL Formatter helps you see what’s at stake clearly.

See also

Related tools

Advertisement