Scientific Notation for ML Scale
One digit, a point, and a power of ten compress any scale from thousandths of a loss to billions of parameters. ML counts in these powers constantly.
Why Does This Exist?
ML lives at scales everyday notation cannot hold. Learning rates like . Datasets of images. Models of parameters. Written longhand these numbers hide their size in zero-counting; written as powers of ten their size is the first thing you see.
Scientific notation writes any number as with . The exponent names the scale, the digit names the detail. Memory budgets, learning-rate grids, loss magnitudes and paper results all speak it, and misreading one exponent is a thousand-fold error. How the machine stores these powers, with what rounding, is the job of floating-point formats; keeping arithmetic safe across scales is numerical stability.
The one idea you need first. is 1 followed by zeros: . is the mirror: . The exponent counts how far the point moves.
Think of It Like This
Warehouse aisle labels
A warehouse labels aisles A through Z and shelves 001 through 999. Told "aisle C, shelf 042", you walk past the letters, then count shelves. The letter sets the scale of the search, the number finishes it.
An exponent is the aisle, the leading digit the shelf. In , the walks you to billions and the counts seven of them. Two numbers with different exponents live in different aisles; comparing with is decided by the aisle before the shelf is ever read.
Where it stops: aisles are evenly real, while exponents are logarithmic, each aisle ten times the last. The analogy shows the two-part reading; the arithmetic below shows the ten-fold jumps.
How It Actually Works
Convert by moving the point until one nonzero digit stands before it, counting the moves as the exponent. moves the point 9 places: . moves it 4 places right: . In code the becomes e: 7e9, 2e-4.
Arithmetic follows the exponents. Multiply by adding exponents: . Divide by subtracting: . Compare by exponent first: any beats any no matter the leading digits.
Worked example: weighing a 7-billion-parameter model
Parameters: . Half-precision bytes each: .
Multiply: bytes. (The last step renormalises: is not below 10, so shift one power across: .)
Read it: bytes is , fourteen gigabytes. One multiplication, decided before a single weight loads. The diagram above puts this count on the same ladder as a learning rate: twelve orders of magnitude, one picture.
Code
params: float = 7e9bytes_each: int = 2total: float = params * bytes_eachprint(total) # -> 14000000000.0print(f"{total:.1e}") # -> 1.4e+10The float prints fourteen billion the long way, then the format specifier prints what a human reads: 1.4e+10. Note 7e9 is a float in Python, exact here because the value fits, but never hand it to range().
Watch Out For
Handing 1e9 to range()
1e9 looks like a billion and prints like one, but it is a float, and range(1e9) raises TypeError. The symptom is a crash on a line that reads perfectly, usually inside a data-loading loop written with scientific notation for clarity.
Convert at the boundary: range(int(1e9)). Keep floats for measurement, ints for counting, and convert explicitly where they meet.
Adding numbers from different aisles
in float arithmetic is : the 1 falls off the end of the precision and vanishes. Accumulating a million small gradients into a large weight sum loses the small ones exactly this way, and the loss plateaus for no visible reason.
Sum small values together first, then add the large one, or use logarithms where only the scale matters. If a metric ignores new data, suspect absorption before suspecting the model.
The Quick Version
- with ; the exponent names the scale, the digit the detail.
- Multiply by adding exponents, divide by subtracting, compare exponents before digits.
- parameters at 2 bytes is bytes, about 14 GB.
1e9is a float: convert withint()before counting or ranging.- Never add across distant scales directly; the small value gets absorbed.