Arithmetic

Integers

In 1994, a Pentium chip divided numbers incorrectly because of a bit error in its integer lookup table. Intel spent 475 million USD replacing units. In 2006, Java's binary search had a bug: mid = (lo + hi) / 2 silently overflowed int32 on arrays longer than a billion elements - a bug that sat undetected for nine years. Both incidents trace back to the same root: what integers look like when they live in hardware.

  • **L1 vs L2 loss in ML**: |y - y_hat| versus (y - y_hat)^2 - one symbol difference changes model behaviour on outliers
  • **Two's complement**: how -5 is stored in bits, and why int32 overflow produces a negative number rather than an error
  • **Modular arithmetic**: RSA, hash functions, ring buffers in PyTorch DataLoader - all built on Z_n

Brahmagupta: A Thousand Years Ahead

Indian mathematician **Brahmagupta**, in *Brahmasphutasiddhanta*, was the first to write explicit rules for arithmetic with positive numbers ('dhana' - property), negative numbers ('rina' - debt), and zero. His sign rule: 'the product of two debts is property' - exactly minus times minus equals plus, the rule taught in schools today.

Debt subtracted from zero is property. Property subtracted from zero is debt.

Brahmagupta's sign rules from 628 CE are the direct ancestors of integer arithmetic in every programming language.

Why Negative Numbers Exist

In 1994, Intel's Pentium processor produced wrong division results due to a bit-level error in its floating-point unit lookup table. The recall cost 475 million USD. Integers are not an abstraction from a textbook - they live inside every chip, and errors in their representation have measurable financial consequences.

Natural numbers handle counting. Subtraction breaks them: the equation $x + 5 = 3$ has no solution in $\mathbb{N}$. The question itself is perfectly real - 'what quantity, after adding 5, yields 3?' - but the answer, $x = -2$, falls outside the natural number line. To represent debt, deficit, or direction, numbers to the left of zero are needed.

16th-century European mathematicians called negative numbers *numeri absurdi*. Pascal called them fiction. Descartes admitted them reluctantly. Meanwhile, merchants, bankers, and military engineers kept using them to track debts and deficits. Practice outlasted philosophy by about five centuries.

Why does x + 5 = 3 have no solution in the natural numbers?

The Set Z and the Number Line

**Integers** $\mathbb{Z}$ are the natural numbers, zero, and their negatives. The notation comes from the German *Zahlen* - 'numbers'. Formally: $\mathbb{Z} = \{\ldots, -3, -2, -1, 0, 1, 2, 3, \ldots\}$. Natural numbers are a subset: $\mathbb{N} \subset \mathbb{Z}$.

**Opposite number:** for every $n \in \mathbb{Z}$ there exists $-n$ such that $n + (-n) = 0$. This defines zero as the additive identity and makes $\mathbb{Z}$ an **abelian group** under addition - the algebraic structure underlying all of cryptography.

Integers are **closed** under $+$, $-$, $\times$: applying any of these to two integers always yields an integer. Division breaks this: $7 \div 3 \notin \mathbb{Z}$. That gap is exactly what motivates fractions and rational numbers.

Which statement is true?

Absolute Value: Distance and L1 Loss

The **absolute value** of $x$ is its distance from zero on the number line, written $|x|$. Not 'drop the minus sign' - distance. The distinction matters: distance is always non-negative and defined geometrically, which is what makes the concept generalize beyond numbers.

In machine learning, $|y - \hat{y}|$ is **L1 loss** (Mean Absolute Error). Compare to L2 loss $(y - \hat{y})^2$: the square penalizes large errors disproportionately, so models trained with L2 are sensitive to outliers. L1 is robust - a single anomalous point does not dominate the gradient. One symbol change ($|\cdot|$ versus $(\cdot)^2$) changes the behaviour of the entire system on real data.

**Sign function:** $\text{sign}(x) = x / |x|$ for $x \ne 0$. The subgradient of L1 loss with respect to $\hat{y}$ is $-\text{sign}(y - \hat{y})$ - a constant step of $\pm 1$, unlike L2 whose gradient grows linearly with the error. An outlier pulls an L1-trained model with the same force as any normal point. An L2-trained model is pulled in proportion to the error magnitude.

Absolute value just removes the minus sign

Absolute value is distance to zero; for positive numbers it changes nothing

|5| = 5 not because a non-existent minus was removed, but because 5 is already 5 units from zero. The distance definition extends to vectors, functions, and metric spaces - where 'drop the minus' has no meaning.

Why is L1 loss (MAE) more robust to outliers than L2 loss (MSE)?

How CPUs Store Negative Integers

Computers store numbers in bits. Positive integers are straightforward: 5 = 101. Storing -5 is not. The naive approach - reserve the top bit as a sign flag - produces a 'negative zero' (-0 and +0 as distinct bit patterns) and breaks addition. Engineers at Intel and DEC in the 1960s chose a different encoding: **two's complement**.

Two practical consequences for ML work. First: arithmetic right shift ($x >> 1$) for negative numbers in C/Java is implementation-defined. Python behaves consistently: $-7 // 2 = -4$ (floor division, rounds toward negative infinity) rather than $-3$. Second: int32 overflow in NumPy wraps around silently. Adding 1 to the maximum int32 value produces the minimum int32 value. Without knowing two's complement, the result looks like a random bug.

**Why -1 >> 1 can equal -1 in C:** arithmetic right shift propagates the sign bit rather than filling with zeros. -1 in two's complement is all ones (0xFF...F). Shifting right by 1 copies the sign bit - the result is still all ones, still -1. Python uses the same arithmetic shift: `-1 >> 1` is -1 in Python as well.

Why does int32 overflow in NumPy at 2^31 - 1 + 1 give -2^31 instead of an error?

Key Ideas

  • $\mathbb{Z} = \{\ldots, -2, -1, 0, 1, 2, \ldots\}$ - extends $\mathbb{N}$ to solve $x + a = b$ when $a > b$
  • Number line: further right = greater; among negatives, -1 > -100
  • $|x|$ - distance to zero; in ML this is L1 loss, robust to outliers
  • Two's complement: how CPUs store negatives - int32/int64 overflow is arithmetic mod $2^{32}$, not a bug
  • $\mathbb{Z}$ closed under $+$, $-$, $\times$; not closed under $\div$ - motivation for $\mathbb{Q}$

Related Topics

Integers are a foundation - here is what builds on them:

  • Addition and Subtraction — Integer operations - sign rules in practice
  • Rational Numbers — The next extension: Q closes Z under division
  • Modular Arithmetic — Arithmetic of remainders - foundation of hash functions and cryptography
  • Binary Representation — Two's complement - storing integers in CPUs
  • Computer Arithmetic — int32/int64 overflow in NumPy and C

Вопросы для размышления

  • Why did European mathematicians resist negative numbers for a thousand years, given that debt and deficit are everyday concepts?
  • How does knowing two's complement explain why -1 % 2 == 1 in Python but -1 % 2 == -1 in C?
  • L1 loss uses |x|, L2 loss uses x^2. Construct a scenario where L2 is the better choice.

Связанные уроки

  • ar-03-addition — Operations on integers - the immediate next step
  • ar-28-modular — Modular arithmetic builds on the group structure of Z
  • ar-26-binary — Two's complement is how CPUs store negative integers
  • ar-44-crypto-intro — RSA and hash functions operate in rings of integers
  • ar-45-computer-arithmetic — int32/int64 overflow is integers meeting hardware limits
  • calc-01-sequences
Integers

0

1

Sign In