Coding Interview Patterns Module 18 – Maths for coding rounds
Division, remainders and overflow across languages
What -7 / 2 and -7 % 2 give in Python, JavaScript, Java, C++ and Go, how to get floor division and remainders that are never negative, and how to stop overflow.
What you will learn
- Predict the quotient and remainder of a negative division in Python, JavaScript, Java, C++ and Go
- Write floor division, ceiling division and a remainder from 0 to m − 1 in each of the five languages
- Detect overflow before it happens, with an estimate or a checked operation
- Choose big integers when an exact answer outgrows 64 bits
Before you start
What you’ll learn · Before you start
What you will learn
- Predict the quotient and remainder of a negative division in Python, JavaScript, Java, C++ and Go
- Write floor division, ceiling division and a remainder from 0 to m − 1 in each of the five languages
- Detect overflow before it happens, with an estimate or a checked operation
- Choose big integers when an exact answer outgrows 64 bits
Before you start
On this page
Integer division has to round whenever the answer is not whole, and the five languages of this track do not all
round the same way. Python rounds the quotient down: -7 // 2 is −4 and -7 % 2 is 1. Java, C++ and Go round
towards zero: -7 / 2 is −3 and -7 % 2 is −1, and JavaScript gives the same with Math.trunc(-7 / 2) and %. When
a result is too large for its type, the five part ways again: Python’s integers never overflow, Java and Go wrap
around without a word, signed overflow in C++ is undefined behaviour, and a JavaScript Number stops holding every
integer exactly above 2⁵³ − 1. This lesson runs the same divisions and edge cases in all five languages, side by side,
then gives the fixes that hold in each: floor and ceiling division, a remainder from 0 to m − 1, a mean that cannot
overflow, overflow checks and big integers.
Two ways to round a quotient
When b does not divide a, the true quotient has a fraction, and integer division must turn it into a whole number. Two rules are common. Truncation drops the fraction, which moves the quotient towards zero: −3.5 becomes −3. Floor division rounds down, towards minus infinity: −3.5 becomes −4. For operands of the same sign the two give the same answer, because 3.5 truncated and 3.5 rounded down are both 3. They differ only when exactly one operand is negative and the division leaves a remainder.
The remainder is never chosen on its own. Every language here defines it so that quotient and remainder rebuild the dividend, a = q × b + r, so the remainder follows from the quotient: r = a − q × b. With truncation, −7 − (−3 × 2) = −1, and the remainder has the sign of the dividend. With floor division, −7 − (−4 × 2) = 1, and the remainder has the sign of the divisor.
One division, two roundings, two remainders
Text description of the diagram
The diagram shows one box at the top with two arrows leading down to two boxes side by side.
1. The top box reads: −7 ÷ 2 = −3.5, which is not a whole number, so an integer quotient must round. 2. The arrow labelled "truncate" leads to the box "Towards zero: −3", used by Java, C++, Go and JavaScript. The remainder that goes with it is −7 − (−3 × 2) = −1, which has the sign of the dividend, −7. 3. The arrow labelled "floor" leads to the box "Down: −4", used by Python. The remainder that goes with it is −7 − (−4 × 2) = 1, which has the sign of the divisor, 2.
The language specifications split the five like this:
- Python floors. Its reference says that floor division of integers applies the floor function to the
mathematical quotient, and that
%returns a result with the sign of its second operand, so thatx == (x // y) * y + x % yalways holds.divmod(a, b)returns both. - Java truncates: its specification says that integer division rounds toward 0, and that
(a / b) * b + (a % b)equalsa. - C++ truncates as well: the fractional part of the quotient is discarded.
- Go truncates, and its specification calls it truncated division:
x = q*y + rwith|r| < |y|. - JavaScript has no integer division for Numbers.
-7 / 2is −3.5, and you choose the rounding withMath.truncorMath.floor. Its%truncates, so the remainder has the sign of the dividend. BigInt division truncates too, so-7n / 2nis-3n.
A third convention, the Euclidean remainder, is never negative: it lies from 0 to |b| − 1 whatever the signs. No
operator of the five uses it, but it is what “a mod m” means in mathematics. For a positive divisor it equals the
floor remainder, which is why Python’s % and Java’s Math.floorMod give it whenever m is positive. Go’s math/big
package offers both families: Quo and Rem truncate like Go’s operators, while Div and Mod are Euclidean.
The same divisions in five languages
Here are four divisions, one for each pair of signs, and three edge cases, in Python and in JavaScript, where BigInt takes over the 64-bit rows:
Python · table/table.py
# Division, remainder and three edge cases with Python's int.
pairs = [(7, 2), (-7, 2), (7, -2), (-7, -2)]
for a, b in pairs:
print(f"{a} // {b} = {a // b}, {a} % {b} = {a % b}")
# The 64-bit limits, where Java's long, C++'s long long and Go's int64 run out.
largest, smallest = 2**63 - 1, -(2**63)
print("largest + 1 =", largest + 1)
print("smallest // -1 =", smallest // -1)
try:
print(7 // 0)
except ZeroDivisionError as error:
print("7 // 0 raises ZeroDivisionError:", error) Output
7 // 2 = 3, 7 % 2 = 1 -7 // 2 = -4, -7 % 2 = 1 7 // -2 = -4, 7 % -2 = -1 -7 // -2 = 3, -7 % -2 = -1 largest + 1 = 9223372036854775808 smallest // -1 = 9223372036854775808 7 // 0 raises ZeroDivisionError: division by zero
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 table.py
JavaScript · table/table.mjs
// Division, remainder and three edge cases in JavaScript: Numbers, then BigInt.
const pairs = [[7, 2], [-7, 2], [7, -2], [-7, -2]];
for (const [a, b] of pairs) {
console.log(`Math.trunc(${a} / ${b}) = ${Math.trunc(a / b)}, ${a} % ${b} = ${a % b}`);
}
for (const [a, b] of pairs) {
const x = BigInt(a);
const y = BigInt(b);
console.log(`${x}n / ${y}n = ${x / y}n, ${x}n % ${y}n = ${x % y}n`);
}
// A Number holds every integer exactly only up to 2^53 - 1, so the 64-bit limits need BigInt.
console.log('MAX_SAFE_INTEGER + 2 =', Number.MAX_SAFE_INTEGER + 2);
const largest = 2n ** 63n - 1n;
const smallest = -(2n ** 63n);
console.log(`largest + 1n = ${largest + 1n}n`);
console.log(`smallest / -1n = ${smallest / -1n}n`);
console.log(`7 / 0 = ${7 / 0}, 7 % 0 = ${7 % 0}`);
try {
console.log(7n / 0n);
} catch (error) {
console.log('7n / 0n throws', error.name);
} Output
Math.trunc(7 / 2) = 3, 7 % 2 = 1 Math.trunc(-7 / 2) = -3, -7 % 2 = -1 Math.trunc(7 / -2) = -3, 7 % -2 = 1 Math.trunc(-7 / -2) = 3, -7 % -2 = -1 7n / 2n = 3n, 7n % 2n = 1n -7n / 2n = -3n, -7n % 2n = -1n 7n / -2n = -3n, 7n % -2n = 1n -7n / -2n = 3n, -7n % -2n = -1n MAX_SAFE_INTEGER + 2 = 9007199254740992 largest + 1n = 9223372036854775808n smallest / -1n = 9223372036854775808n 7 / 0 = Infinity, 7 % 0 = NaN 7n / 0n throws RangeError
Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node table.mjs
Runs on this device, in your browser. The first run of each language downloads it: Python (about 13.5 MB) or JavaScript (about 0.6 MB), which is kept for the next runs.
Your run, in this browser
Here is the same program in Java, C++ and Go, built and run with the track’s pinned versions. The C++ build turns on the undefined-behaviour sanitizer, which checks the arithmetic while the program runs and reports each operation whose result the language leaves undefined:
Java · compiled/Table.java
// Division, remainder and three edge cases with Java's int and long.
class Table {
public static void main(String[] args) {
int[][] pairs = {{7, 2}, {-7, 2}, {7, -2}, {-7, -2}};
for (int[] p : pairs) {
int a = p[0], b = p[1];
System.out.println(a + " / " + b + " = " + (a / b) + ", " + a + " % " + b + " = " + (a % b));
}
long largest = Long.MAX_VALUE, smallest = Long.MIN_VALUE;
System.out.println("largest + 1 = " + (largest + 1));
System.out.println("smallest / -1 = " + (smallest / -1));
int zero = 0;
try {
System.out.println(7 / zero);
} catch (ArithmeticException e) {
System.out.println("7 / 0 throws ArithmeticException: " + e.getMessage());
}
}
} C++ · compiled/table.cpp
// Division, remainder and three edge cases with C++'s int and long long.
#include <climits>
#include <iostream>
int main() {
std::cout << std::unitbuf; // print each line at once, so it comes before the sanitizer's report
int pairs[4][2] = {{7, 2}, {-7, 2}, {7, -2}, {-7, -2}};
for (auto [a, b] : pairs) {
std::cout << a << " / " << b << " = " << a / b << ", " << a << " % " << b << " = " << a % b << '\n';
}
// volatile: the values are read when the program runs, so the compiler cannot work the results out in advance.
// Each result is computed before its line is printed, so a sanitizer report comes just above that line.
volatile long long largest = LLONG_MAX, smallest = LLONG_MIN, zero = 0;
long long sum = largest + 1;
std::cout << "largest + 1 = " << sum << '\n';
long long quotient = smallest / -1;
std::cout << "smallest / -1 = " << quotient << '\n';
long long by_zero = 7 / zero;
std::cout << "7 / 0 = " << by_zero << '\n';
} Go · compiled/table.go
// Division, remainder and three edge cases with Go's int and int64.
package main
import (
"fmt"
"math"
)
func main() {
pairs := [][2]int{{7, 2}, {-7, 2}, {7, -2}, {-7, -2}}
for _, p := range pairs {
a, b := p[0], p[1]
fmt.Printf("%d / %d = %d, %d %% %d = %d\n", a, b, a/b, a, b, a%b)
}
var largest, smallest, minusOne int64 = math.MaxInt64, math.MinInt64, -1
fmt.Println("largest + 1 =", largest+1)
fmt.Println("smallest / -1 =", smallest/minusOne)
divideByZero()
}
// divideByZero divides by a variable that holds 0 (a constant 0 does not compile) and prints the panic it causes.
func divideByZero() {
defer func() { fmt.Println("7 / 0 panics:", recover()) }()
zero := 0
fmt.Println(7 / zero)
} Build and run all three · compiled/table_session.py
from session import run, versions
# Table.java runs as a single source file, table.cpp is built with the undefined-behaviour sanitizer, and go run
# builds table.go.
versions("java -version", "clang++ --version", "go version")
run("""
java Table.java
clang++ -std=c++23 -Wall -Wextra -fsanitize=undefined table.cpp -o table && ./table
go run table.go
""") Output
# openjdk version "25.0.4.1" LTS # Apple clang version 21.0.0 (clang-2100.3.34.2) # go version go1.27.1 darwin/arm64 $ java Table.java 7 / 2 = 3, 7 % 2 = 1 -7 / 2 = -3, -7 % 2 = -1 7 / -2 = -3, 7 % -2 = 1 -7 / -2 = 3, -7 % -2 = -1 largest + 1 = -9223372036854775808 smallest / -1 = -9223372036854775808 7 / 0 throws ArithmeticException: / by zero $ clang++ -std=c++23 -Wall -Wextra -fsanitize=undefined table.cpp -o table && ./table 7 / 2 = 3, 7 % 2 = 1 -7 / 2 = -3, -7 % 2 = -1 7 / -2 = -3, 7 % -2 = 1 -7 / -2 = 3, -7 % -2 = -1 table.cpp:16:29: runtime error: signed integer overflow: 9223372036854775807 + 1 cannot be represented in type 'long long' largest + 1 = -9223372036854775808 table.cpp:18:35: runtime error: division of -9223372036854775808 by -1 cannot be represented in type 'long long' smallest / -1 = -9223372036854775808 table.cpp:20:27: runtime error: division by zero 7 / 0 = 0 $ go run table.go 7 / 2 = 3, 7 % 2 = 1 -7 / 2 = -3, -7 % 2 = -1 7 / -2 = -3, 7 % -2 = 1 -7 / -2 = 3, -7 % -2 = -1 largest + 1 = -9223372036854775808 smallest / -1 = -9223372036854775808 7 / 0 panics: runtime error: integer divide by zero
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 table_session.py
All five recorded runs agree whenever both operands have the same sign. The pairs with mixed signs are where the languages split, and Python is the one that differs from the other four, Java, C++, Go and JavaScript:
| Case | Python | The other four |
|---|---|---|
| −7 ÷ 2 | −4 | −3 |
| −7 % 2 | 1 | −1 |
| 7 % −2 | −1 | 1 |
JavaScript reaches −3 with Math.trunc(a / b), and BigInt’s / gives the same. So if a solution divides values that
can be negative, such as changes in a balance, coordinates or temperatures, the language decides the answer.
At the 64-bit limits, 2⁶³ − 1 and −2⁶³, and at zero, the runs part ways further:
- Python stays exact: both edge results are 2⁶³, and
7 // 0raisesZeroDivisionError. - JavaScript gives 2⁶³ for both as a BigInt. With Numbers,
7 / 0isInfinityand7 % 0isNaN, and both flow on into later arithmetic without an error;7n / 0nthrows aRangeError. - Java wraps both results to −2⁶³ without an error, and
7 / 0throws anArithmeticException. - C++ leaves all three undefined, and the sanitizer reported each one. The numbers printed after the reports are only what this computer’s processor returned: undefined behaviour carries no promise at all, and another compiler or optimisation level may print something else or stop the program.
- Go wraps both results to −2⁶³ without a panic, and
7 / 0panics at run time. It also rejects a division by a constant zero when it compiles, which is whytable.godivides by a variable that holds 0.
The most negative value divided by −1 is the case people forget: its true result, 2⁶³, is one more than the largest
64-bit value, so the division itself overflows. Java and Go define the result as the dividend, with a remainder of 0.
JavaScript needed BigInt for these rows because a Number holds every integer exactly only up to 2⁵³ − 1:
MAX_SAFE_INTEGER + 2 printed 9007199254740992, the same Number as MAX_SAFE_INTEGER + 1.
Floor division and remainders from 0 to m − 1
Many problems need the floor behaviour in a language that truncates: the weekday 10 days before a Monday, a position
that moves backwards around a ring, a bucket for a hash that may be negative. Java has it in its library: Math.floorDiv
and Math.floorMod for int and long, and, from Java 18, Math.ceilDiv for a quotient rounded up.
In C++, Go and JavaScript you write it yourself. For a remainder from 0 to m − 1 with a positive m, take r = a % m
and add m only when r came out negative. At that point r lies between −m and 0, so r + m lies between 0 and m and
cannot overflow. Many solutions write the same idea as one expression, ((a % m) + m) % m. In exact arithmetic it
gives the same answers, but it adds m even when a % m is already positive, so the sum in the middle can reach
2m − 2. Here are both forms in Java, for the usual modulus 10⁹ + 7 and for 2,147,483,647, the largest int, with
Math.floorMod as the reference:
Java · compiled/Remainders.java
// A remainder from 0 to m - 1 with Java's int, then floor and ceiling division.
class Remainders {
// Adds m even when a % m is already positive: the sum can pass Integer.MAX_VALUE.
static int textbook(int a, int m) {
return ((a % m) + m) % m;
}
// r + m lies between 0 and m when r is negative, so it always fits.
static int addIfNegative(int a, int m) {
int r = a % m;
return r < 0 ? r + m : r;
}
public static void main(String[] args) {
for (int m : new int[] {1_000_000_007, Integer.MAX_VALUE}) {
for (int a : new int[] {-1, 5}) {
System.out.printf("a = %d, m = %d: textbook %d, add if negative %d, Math.floorMod %d%n",
a, m, textbook(a, m), addIfNegative(a, m), Math.floorMod(a, m));
}
}
System.out.println("Math.floorDiv(-7, 2) = " + Math.floorDiv(-7, 2) + ", Math.floorMod(7, -2) = " + Math.floorMod(7, -2));
System.out.println("Math.ceilDiv(7, 2) = " + Math.ceilDiv(7, 2) + ", Math.ceilDiv(-7, 2) = " + Math.ceilDiv(-7, 2));
}
} Run it · compiled/remainders_session.py
from session import run, versions
versions("java -version")
run("""
java Remainders.java
""") Output
# openjdk version "25.0.4.1" LTS $ java Remainders.java a = -1, m = 1000000007: textbook 1000000006, add if negative 1000000006, Math.floorMod 1000000006 a = 5, m = 1000000007: textbook 5, add if negative 5, Math.floorMod 5 a = -1, m = 2147483647: textbook 2147483646, add if negative 2147483646, Math.floorMod 2147483646 a = 5, m = 2147483647: textbook -2147483644, add if negative 5, Math.floorMod 5 Math.floorDiv(-7, 2) = -4, Math.floorMod(7, -2) = -1 Math.ceilDiv(7, 2) = 4, Math.ceilDiv(-7, 2) = -3
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 remainders_session.py
For 10⁹ + 7 the largest sum, 2 × (10⁹ + 7) − 2 = 2,000,000,012, still fits below the int limit, and every form
agrees. For 2,147,483,647, 5 % m + m passes the limit and wraps around, so the one-line form returns −2,147,483,644
for a = 5. The same thing happens in JavaScript one level up, where the sum passes 2⁵³ − 1 and is rounded instead:
// A remainder from 0 to m - 1 in JavaScript, two ways, against the exact answer that BigInt gives.
const textbook = (a, m) => ((a % m) + m) % m; // adds m even when a % m is already positive
const addIfNegative = (a, m) => {
const r = a % m;
return r < 0 ? r + m : r; // r + m lies between 0 and m here, so it never leaves the exact range
};
const exact = (a, m) => Number(((BigInt(a) % BigInt(m)) + BigInt(m)) % BigInt(m));
for (const m of [7, Number.MAX_SAFE_INTEGER]) {
for (const a of [-1, 6]) {
console.log(`a = ${a}, m = ${m}: textbook ${textbook(a, m)}, add if negative ${addIfNegative(a, m)}, exact ${exact(a, m)}`);
}
}
// % keeps the sign of a, even when the remainder is zero.
console.log('-4 % 2 is', -4 % 2, 'and equals 0:', -4 % 2 === 0);
console.log('add if negative, then + 0:', addIfNegative(-4, 2) + 0); Output
a = -1, m = 7: textbook 6, add if negative 6, exact 6 a = 6, m = 7: textbook 6, add if negative 6, exact 6 a = -1, m = 9007199254740991: textbook 9007199254740990, add if negative 9007199254740990, exact 9007199254740990 a = 6, m = 9007199254740991: textbook 5, add if negative 6, exact 6 -4 % 2 is -0 and equals 0: true add if negative, then + 0: 0
Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node remainders.mjs
Runs on this device, in your browser. The first run downloads JavaScript (about 0.6 MB), which is kept for the next runs.
Your run, in this browser
With m = 2⁵³ − 1, the one-line form returns 5 for a = 6. The last two lines show a quirk of JavaScript’s %: a
remainder of zero keeps the sign of a, as the ECMAScript specification requires, so -4 % 2 is -0. It equals 0
in every comparison, but console.log prints it as -0, and an online judge that compares printed text can mark
that as a wrong answer. Adding 0 turns it into a plain 0.
A floor quotient in C++ or Go takes one more step: truncate, then subtract 1 when the division left a remainder and
the operands had opposite signs. A ceiling quotient adds 1 instead, when there was a remainder and the signs were
the same. The common shortcut for a quotient rounded up, (a + b - 1) / b, is right only for a ≥ 0 and b > 0, and
its sum can overflow when a is near the limit. For positive values, a / b, plus 1 when a % b is not 0, has
neither problem. In JavaScript, Math.trunc(a / b), Math.floor(a / b) and Math.ceil(a / b) are exact for safe
integers: the true quotient of two such numbers is never close enough to a whole number for the rounding of / to
reach it.
Python has the floor forms built in, and a ceiling quotient is -(-a // b), exact for any size. What it lacks is a
quotient rounded towards zero, which a solution ported from Java needs, or a problem that says the fraction is
dropped. int(a / b) is the usual answer, and it holds only while the quotient fits a float exactly:
# Rounding a quotient towards zero in Python, as Java, C++, Go and JavaScript do.
# // rounds down instead, and a / b is a float, which holds whole numbers exactly only up to 2**53.
for a, b in [(-7, 2), (7, -2), (10**20 + 7, 3), (-(10**20 + 7), 3)]:
print(f"a = {a}, b = {b}")
print(f" a // b = {a // b}")
print(f" int(a / b) = {int(a / b)}") Output
a = -7, b = 2 a // b = -4 int(a / b) = -3 a = 7, b = -2 a // b = -4 int(a / b) = -3 a = 100000000000000000007, b = 3 a // b = 33333333333333333335 int(a / b) = 33333333333333331968 a = -100000000000000000007, b = 3 a // b = -33333333333333333336 int(a / b) = -33333333333333331968
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 truncate.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
For 10²⁰ + 7 divided by 3, int(a / b) is off by 1,367, because a / b became a float with 53 bits of precision
first. For the negative dividend, // rounds the wrong way as well. Exact truncation divides the absolute values
with // and then gives the result its sign.
Overflow: estimate first, then check
Overflow gives a wrong number without an error message, so the defence starts before the code: estimate the largest
value each variable can hold from the limits in the statement. A 64-bit signed integer holds up to 2⁶³ − 1, about
9.2 × 10¹⁸, so the product of two values up to 10⁹ fits (10¹⁸) and the product of three does not (10²⁷). A 32-bit
int holds up to 2,147,483,647, about 2.1 × 10⁹, which the sum of three values of 10⁹ already passes. The
lesson on reading constraints works through this estimate for
sums; for a product, add the exponents.
When the estimate is close, or the values come from somewhere you cannot bound, check the operation itself. Here is the volume of a box whose sides are 10⁹, in Java, C++ and Go:
Java · compiled/Checked.java
import java.math.BigInteger;
// The Exact methods of java.lang.Math throw ArithmeticException where plain operators would wrap around.
class Checked {
interface Step {
Object run();
}
static void show(String what, Step step) {
try {
System.out.println(what + " = " + step.run());
} catch (ArithmeticException e) {
System.out.println(what + " throws ArithmeticException: " + e.getMessage());
}
}
public static void main(String[] args) {
long side = 1_000_000_000L;
long area = side * side; // 10^18 still fits in a long
show("multiplyExact(side, side)", () -> Math.multiplyExact(side, side));
show("area * side", () -> area * side);
show("multiplyExact(area, side)", () -> Math.multiplyExact(area, side));
show("BigInteger side^3", () -> BigInteger.valueOf(side).pow(3));
show("toIntExact(3_000_000_000L)", () -> Math.toIntExact(3_000_000_000L));
show("Math.abs(Integer.MIN_VALUE)", () -> Math.abs(Integer.MIN_VALUE));
show("absExact(Integer.MIN_VALUE)", () -> Math.absExact(Integer.MIN_VALUE));
show("divideExact(Integer.MIN_VALUE, -1)", () -> Math.divideExact(Integer.MIN_VALUE, -1));
}
} C++ · compiled/checked.cpp
// __builtin_mul_overflow (GCC and Clang) multiplies, stores the low bits and says whether the true result fitted.
#include <iostream>
int main() {
long long side = 1'000'000'000, area = 0, volume = 0;
bool overflowed = __builtin_mul_overflow(side, side, &area);
std::cout << std::boolalpha << "area = " << area << ", overflowed: " << overflowed << '\n';
overflowed = __builtin_mul_overflow(area, side, &volume);
std::cout << "volume overflowed: " << overflowed << " (the low 64 bits hold " << volume << ")\n";
} Go · compiled/checked.go
// Go has no checked multiplication: test the limit before multiplying, and use math/big beyond 64 bits.
package main
import (
"fmt"
"math"
"math/big"
)
// mulFits reports whether a * b fits in an int64, for a and b that are not negative.
func mulFits(a, b int64) bool {
return b == 0 || a <= math.MaxInt64/b
}
func main() {
side := int64(1_000_000_000)
area := side * side
fmt.Println("area =", area, "fits:", mulFits(side, side))
fmt.Printf("volume fits: %v (area * side wraps to %d)\n", mulFits(area, side), area*side)
volume := new(big.Int).Exp(big.NewInt(side), big.NewInt(3), nil)
fmt.Println("volume as a big.Int =", volume)
} Build and run all three · compiled/checks_session.py
from session import run, versions
versions("java -version", "clang++ --version", "go version")
run("""
java Checked.java
clang++ -std=c++23 -Wall -Wextra -fsanitize=undefined checked.cpp -o checked && ./checked
go run checked.go
""") Output
# openjdk version "25.0.4.1" LTS # Apple clang version 21.0.0 (clang-2100.3.34.2) # go version go1.27.1 darwin/arm64 $ java Checked.java multiplyExact(side, side) = 1000000000000000000 area * side = -6930898827444486144 multiplyExact(area, side) throws ArithmeticException: long overflow BigInteger side^3 = 1000000000000000000000000000 toIntExact(3_000_000_000L) throws ArithmeticException: integer overflow Math.abs(Integer.MIN_VALUE) = -2147483648 absExact(Integer.MIN_VALUE) throws ArithmeticException: Overflow to represent absolute value of Integer.MIN_VALUE divideExact(Integer.MIN_VALUE, -1) throws ArithmeticException: integer overflow $ clang++ -std=c++23 -Wall -Wextra -fsanitize=undefined checked.cpp -o checked && ./checked area = 1000000000000000000, overflowed: false volume overflowed: true (the low 64 bits hold -6930898827444486144) $ go run checked.go area = 1000000000000000000 fits: true volume fits: false (area * side wraps to -6930898827444486144) volume as a big.Int = 1000000000000000000000000000
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 checks_session.py
- Java: the
Exactmethods ofMaththrowArithmeticExceptionwhere the operator would wrap:addExactandmultiplyExactfor sums and products,toIntExactfor alongthat must become anint,absExactfor the one value whose absolute value does not fit (plainMath.abs(Integer.MIN_VALUE)returns a negative number, as its documentation warns) anddivideExactfor the most negative value divided by −1. - C++: GCC and Clang provide
__builtin_add_overflow,__builtin_sub_overflowand__builtin_mul_overflow, which compute the result, store its low bits and return whether the true result fitted. While you practise, build with-fsanitize=undefined, as the table above was, so that a signed overflow is reported where it happens. - Go: there is no checked operator, so compare with the limit before multiplying. For values that are not
negative,
b == 0 || a <= math.MaxInt64/bsays that the product fits. - Python: there is nothing to check, because its integers have unlimited precision.
- JavaScript: a Number that grows too large is rounded rather than wrapped, so the question is whether the result is still exact:
// In JavaScript, a result that is too large is rounded, not wrapped. Number.isSafeInteger says when that can happen.
const a = 999_999_999;
const product = a * a;
console.log('a * a =', product, '- safe integer:', Number.isSafeInteger(product));
console.log('as BigInt:', BigInt(a) * BigInt(a));
const side = 1_000_000_000n;
console.log('side ** 3n =', side ** 3n);
try {
console.log(side + 1);
} catch (error) {
console.log('side + 1 throws', error.name, '(BigInt and Number do not mix)');
} Output
a * a = 999999998000000000 - safe integer: false as BigInt: 999999998000000001n side ** 3n = 1000000000000000000000000000n side + 1 throws TypeError (BigInt and Number do not mix)
Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node checks.mjs
Runs on this device, in your browser. The first run downloads JavaScript (about 0.6 MB), which is kept for the next runs.
Your run, in this browser
999,999,999 squared is 999,999,998,000,000,001, but the Number ends in 000, and Number.isSafeInteger returns false
for it. For addition, subtraction and multiplication of safe integers, that test is exact: a result that is a safe
integer was computed without rounding, and a true result above 2⁵³ − 1 can only round to a number that fails the
test. BigInt gives the exact value, but it never mixes with Numbers in one expression, so convert every operand.
Version note
Math.floorDiv, Math.floorMod, addExact, multiplyExact and toIntExact arrived in Java 8, absExact in
Java 15, and ceilDiv and divideExact in Java 18, so all of them run on Java 21 and later. std::midpoint
needs C++20, and so does the rule that >> rounds a negative value down: before C++20, shifting a negative value
to the right gave an implementation-defined result.
A mean of two integers that cannot overflow
The mean of two values rounded down looks like (a + b) / 2, and it overflows whenever a + b does. The usual fix,
a + (b - a) / 2, has limits of its own. Here are four pairs of Java int values, with the exact answer worked out
in long, and three pairs with C++20’s std::midpoint:
Java · compiled/Means.java
// The mean of two ints, rounded down, three ways, and the exact answer worked out in long.
class Means {
public static void main(String[] args) {
int[][] pairs = {{1_500_000_000, 2_000_000_000}, {-2_000_000_000, 2_000_000_000}, {5, -2}, {-3, -4}};
for (int[] p : pairs) {
int a = p[0], b = p[1];
int plain = (a + b) / 2;
int fromA = a + (b - a) / 2;
int halves = (a >> 1) + (b >> 1) + (a & b & 1);
long exact = Math.floorDiv((long) a + b, 2);
System.out.printf("a = %d, b = %d%n (a + b) / 2 = %d, a + (b - a) / 2 = %d, halves = %d, exact = %d%n",
a, b, plain, fromA, halves, exact);
}
}
} C++ · compiled/means.cpp
// std::midpoint (C++20) never overflows, but it rounds towards its first argument, so the order matters.
#include <iostream>
#include <numeric>
int main() {
int pairs[3][2] = {{1'500'000'000, 2'000'000'000}, {5, -2}, {-2, 5}};
for (auto [a, b] : pairs) {
int halves = (a >> 1) + (b >> 1) + (a & b & 1); // >> on a negative int rounds down since C++20
std::cout << "a = " << a << ", b = " << b << ": std::midpoint(a, b) = " << std::midpoint(a, b)
<< ", halves = " << halves << '\n';
}
} Build and run both · compiled/means_session.py
from session import run, versions
versions("java -version", "clang++ --version")
run("""
java Means.java
clang++ -std=c++23 -Wall -Wextra -fsanitize=undefined means.cpp -o means && ./means
""") Output
# openjdk version "25.0.4.1" LTS # Apple clang version 21.0.0 (clang-2100.3.34.2) $ java Means.java a = 1500000000, b = 2000000000 (a + b) / 2 = -397483648, a + (b - a) / 2 = 1750000000, halves = 1750000000, exact = 1750000000 a = -2000000000, b = 2000000000 (a + b) / 2 = 0, a + (b - a) / 2 = -2147483648, halves = 0, exact = 0 a = 5, b = -2 (a + b) / 2 = 1, a + (b - a) / 2 = 2, halves = 1, exact = 1 a = -3, b = -4 (a + b) / 2 = -3, a + (b - a) / 2 = -3, halves = -4, exact = -4 $ clang++ -std=c++23 -Wall -Wextra -fsanitize=undefined means.cpp -o means && ./means a = 1500000000, b = 2000000000: std::midpoint(a, b) = 1750000000, halves = 1750000000 a = 5, b = -2: std::midpoint(a, b) = 2, halves = 1 a = -2, b = 5: std::midpoint(a, b) = 1, halves = 1
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 means_session.py
(a + b) / 2wraps for 1.5 × 10⁹ and 2 × 10⁹ and returns −397,483,648. For −3 and −4 it does not overflow, but it truncates −3.5 to −3 instead of rounding it down to −4.a + (b - a) / 2is the midpoint of a binary search, and it is safe there because the indexes satisfy 0 ≤ lo ≤ hi, sohi - loalways fits. For values of opposite signs,b - aitself overflows: −2 × 10⁹ and 2 × 10⁹ give −2,147,483,648 instead of 0. It also rounds towards a rather than down, so 5 and −2 give 2.(a >> 1) + (b >> 1) + (a & b & 1)is right for all four. A right shift by one is floor division by 2 for signed values in Java and Go, in C++ from C++20, and in Python, so each half is rounded down;a & b & 1adds back the 1 that the two halves lose when both a and b are odd. Each half is at most half the range, so their sum always fits.
std::midpoint never overflows, but it rounds an odd sum towards its first argument: std::midpoint(5, -2) is 2
and std::midpoint(-2, 5) is 1, so the order of the arguments changes the answer. In Python, (a + b) // 2 is
already exact. In JavaScript, >> works on 32-bit integers only, so for larger Numbers the halves come from
Math.floor(a / 2) and Math.floor(b / 2) instead.
When 64 bits are not enough
Some answers are exact integers far beyond 9.2 × 10¹⁸: the volume of the box above, a factorial larger than 20!, or a count that the problem asks for in full rather than modulo 10⁹ + 7. Four of the five languages have integers of any size for them:
- Python: the ordinary
int. - JavaScript:
BigInt, written with annsuffix, such as10n ** 27n. Its/truncates, and it never mixes with Numbers in one expression. - Java:
java.math.BigInteger, which uses methods instead of operators:a.multiply(b). Itsremainderkeeps the sign of the dividend like%, whilemodalways returns a value from 0 to m − 1. - Go:
math/big, whosebig.Intmethods write the result into the value they are called on:z.Mul(x, y). - C++: nothing in the standard library. GCC and Clang offer
__int128as an extension, up to about 1.7 × 10³⁸, and beyond that a solution stores the digits in a vector and carries by hand.
Use them when the statement asks for an exact large value. When it asks for the answer modulo a number, stay with 64-bit integers and take the remainder after every step: each operation then works on small values, and big integers would only add cost.
Exercise
Exercise · Easy · Python, JavaScript
Three integer helpers that hold at the limits
Write three small helpers, in helpers.py for Python or helpers.mjs for JavaScript. Each one must give the exact answer for every input in its range, the largest and smallest values included.
pos_mod(a, m)(JavaScript:posMod) returns the remainder ofadivided bym, from 0 tom − 1, form ≥ 1. It is what Python'sa % mgives for a positivem.floor_mean(a, b)(JavaScript:floorMean) returns the mean ofaandbrounded down, which is Python's(a + b) // 2.trunc_div(a, b)(JavaScript:truncDiv) returnsadivided bybwith the fraction dropped, rounding towards zero as Java, C++ and Go do, forb ≠ 0.
pos_mod(-1, 7) → 6
floor_mean(-3, -4) → -4
floor_mean(5, -2) → 1
trunc_div(-7, 2) → -3
trunc_div(7, -2) → -3
The ranges. In Python, a, b and m are integers of any size, and every result is an int. In JavaScript, they are Numbers that are safe integers, from −(2⁵³ − 1) to 2⁵³ − 1 (m from 1 to 2⁵³ − 1), and every result is a Number that is never -0.
The sample tests check the examples, the edges of each range and 300 random cases against answers worked out another way: with fractions.Fraction in Python and with BigInt in JavaScript.
Python · Starter code · helpers.py
def pos_mod(a, m):
"""The remainder of a divided by m, from 0 to m - 1 (m >= 1)."""
# Replace this line with your code.
return 0
def floor_mean(a, b):
"""The mean of a and b, rounded down."""
# Replace this line with your code.
return 0
def trunc_div(a, b):
"""a divided by b, rounded towards zero (b != 0)."""
# Replace this line with your code.
return 0 The sample tests · test_helpers.py
import math
import random
from fractions import Fraction
from helpers import floor_mean, pos_mod, trunc_div
def test_prompt_examples():
"""the examples from the prompt"""
assert pos_mod(-1, 7) == 6
assert floor_mean(-3, -4) == -4
assert floor_mean(5, -2) == 1
assert trunc_div(-7, 2) == -3
assert trunc_div(7, -2) == -3
def test_pos_mod_from_zero_to_m_minus_one():
"""remainders for a from -4 to 4 with m = 3, and with m = 1"""
assert [pos_mod(a, 3) for a in range(-4, 5)] == [2, 0, 1, 2, 0, 1, 2, 0, 1]
assert [pos_mod(a, 1) for a in (-5, 0, 5)] == [0, 0, 0]
def test_floor_mean_rounds_down():
"""means of an odd total round down, for both signs"""
assert floor_mean(3, 4) == 3
assert floor_mean(-3, 4) == 0
assert floor_mean(4, -3) == 0
assert floor_mean(-1, -2) == -2
assert floor_mean(6, 6) == 6
def test_trunc_div_all_signs():
"""every sign pair, a quotient between -1 and 0, and exact divisions"""
assert [trunc_div(7, 2), trunc_div(-7, 2), trunc_div(7, -2), trunc_div(-7, -2)] == [3, -3, -3, 3]
assert trunc_div(-1, 2) == 0
assert trunc_div(6, -3) == -2
assert trunc_div(0, -5) == 0
def test_values_far_above_two_to_the_53():
"""a float holds whole numbers exactly only up to 2**53, so these need integer arithmetic"""
big = 10**20 + 7
assert trunc_div(big, 3) == 33333333333333333335
assert trunc_div(-big, 3) == -33333333333333333335
assert trunc_div(-(2**63), -1) == 2**63
assert floor_mean(10**30, 10**30 + 1) == 10**30
assert floor_mean(-(10**30), -(10**30) - 1) == -(10**30) - 1
assert pos_mod(-(10**30), 10**9 + 7) == (-(10**30)) % (10**9 + 7)
def test_results_are_ints():
"""every result is an int, never a float"""
for value in (pos_mod(-1, 7), floor_mean(5, -2), trunc_div(-7, 2), trunc_div(10**20 + 7, 3)):
assert type(value) is int, f"{value!r} is a {type(value).__name__}"
def test_random_against_fractions():
"""300 random cases of several sizes, against exact arithmetic with fractions.Fraction"""
rng = random.Random(53)
for _ in range(300):
size = rng.choice([10, 10**6, 2**63, 10**30])
a = rng.randint(-size, size)
b = rng.randint(-size, size) or 1
m = rng.randint(1, size)
assert trunc_div(a, b) == math.trunc(Fraction(a, b)), f"trunc_div({a}, {b})"
assert floor_mean(a, b) == math.floor(Fraction(a + b, 2)), f"floor_mean({a}, {b})"
assert pos_mod(a, m) == a - m * math.floor(Fraction(a, m)), f"pos_mod({a}, {m})" JavaScript · Starter code · helpers.mjs
/** The remainder of a divided by m, from 0 to m - 1 (m >= 1), never -0. */
export function posMod(a, m) {
// Replace this line with your code.
return 0;
}
/** The mean of a and b, rounded down, exact for every safe integer. */
export function floorMean(a, b) {
// Replace this line with your code.
return 0;
}
/** a divided by b, rounded towards zero (b !== 0), never -0. */
export function truncDiv(a, b) {
// Replace this line with your code.
return 0;
} The sample tests · helpers.test.mjs
import { test, assert } from 'mysmartcopilot:test';
import { floorMean, posMod, truncDiv } from './helpers.mjs';
const MAX = Number.MAX_SAFE_INTEGER; // 2^53 - 1
/** Shows -0 as -0 (String(-0) is "0"). */
const show = (x) => (Object.is(x, -0) ? '-0' : String(x));
/** Equal as Object.is sees it: 0 and -0 differ, and the result must be a Number. */
const same = (actual, expected, call) => assert.ok(typeof actual === 'number' && Object.is(actual, expected), `${call}: expected ${show(expected)}, got ${show(actual)}`);
let seed = 53;
const random = () => (seed = (seed * 48271) % 2147483647) / 2147483647;
const randInt = (lo, hi) => lo + Math.floor(random() * (hi - lo + 1));
/** A safe integer: often next to a boundary, sometimes anywhere from -(2^53 - 1) to 2^53 - 1. */
const pick = () => {
const v = random() < 0.5
? Math.min(MAX, [0, 1, 2, 3, 7, 1e6, 2 ** 31, 2 ** 52, MAX - 5][randInt(0, 8)] + randInt(0, 5))
: randInt(0, 2 ** 26 - 1) * 2 ** 27 + randInt(0, 2 ** 27 - 1);
return random() < 0.5 && v !== 0 ? -v : v; // never -0
};
test('the examples from the prompt', () => {
same(posMod(-1, 7), 6, 'posMod(-1, 7)');
same(floorMean(-3, -4), -4, 'floorMean(-3, -4)');
same(floorMean(5, -2), 1, 'floorMean(5, -2)');
same(truncDiv(-7, 2), -3, 'truncDiv(-7, 2)');
same(truncDiv(7, -2), -3, 'truncDiv(7, -2)');
});
test('posMod: from 0 to m - 1, and 0 rather than -0', () => {
const got = [];
for (let a = -4; a <= 4; a++) got.push(posMod(a, 3));
assert.deepEqual(got, [2, 0, 1, 2, 0, 1, 2, 0, 1]);
same(posMod(-4, 2), 0, 'posMod(-4, 2)');
same(posMod(-5, 1), 0, 'posMod(-5, 1)');
same(posMod(-MAX, MAX), 0, 'posMod(-MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)');
});
test('posMod with a modulus near 2^53', () => {
same(posMod(6, MAX), 6, 'posMod(6, MAX_SAFE_INTEGER)');
same(posMod(MAX - 1, MAX), MAX - 1, 'posMod(MAX_SAFE_INTEGER - 1, MAX_SAFE_INTEGER)');
same(posMod(-1, MAX), MAX - 1, 'posMod(-1, MAX_SAFE_INTEGER)');
same(posMod(-MAX, MAX - 1), MAX - 2, 'posMod(-MAX_SAFE_INTEGER, MAX_SAFE_INTEGER - 1)');
});
test('floorMean rounds down, for both signs', () => {
same(floorMean(3, 4), 3, 'floorMean(3, 4)');
same(floorMean(-3, 4), 0, 'floorMean(-3, 4)');
same(floorMean(4, -3), 0, 'floorMean(4, -3)');
same(floorMean(-1, -2), -2, 'floorMean(-1, -2)');
same(floorMean(-1, 1), 0, 'floorMean(-1, 1)');
});
test('floorMean where a + b passes 2^53', () => {
same(floorMean(MAX, MAX - 3), MAX - 2, 'floorMean(MAX_SAFE_INTEGER, MAX_SAFE_INTEGER - 3)');
same(floorMean(MAX, MAX), MAX, 'floorMean(MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)');
same(floorMean(-MAX, -MAX), -MAX, 'floorMean(-MAX_SAFE_INTEGER, -MAX_SAFE_INTEGER)');
same(floorMean(-MAX, -(MAX - 2)), -(MAX - 1), 'floorMean(-MAX_SAFE_INTEGER, -(MAX_SAFE_INTEGER - 2))');
});
test('truncDiv: every sign pair, and 0 rather than -0', () => {
same(truncDiv(7, 2), 3, 'truncDiv(7, 2)');
same(truncDiv(-7, -2), 3, 'truncDiv(-7, -2)');
same(truncDiv(-1, 2), 0, 'truncDiv(-1, 2)');
same(truncDiv(0, -5), 0, 'truncDiv(0, -5)');
same(truncDiv(MAX, -1), -MAX, 'truncDiv(MAX_SAFE_INTEGER, -1)');
});
test('300 random cases against BigInt', () => {
for (let k = 0; k < 300; k++) {
const a = pick();
const b = pick() || 1;
const m = Math.abs(pick()) || 1;
const [A, B, M] = [BigInt(a), BigInt(b), BigInt(m)];
same(truncDiv(a, b), Number(A / B), `truncDiv(${a}, ${b})`);
same(floorMean(a, b), Number((A + B) >> 1n), `floorMean(${a}, ${b})`);
same(posMod(a, m), Number(((A % M) + M) % M), `posMod(${a}, ${m})`);
}
}); A hint
Look for the step where an exact value can be lost. In Python it is a / b, which makes a float: divide the absolute values with // instead, then give the result its sign. In JavaScript it is a + b, which can pass 2⁵³ − 1 even when a and b are safe: halve each number first, rounding down, and add 1 back when both were odd. And % keeps the sign of a, so a remainder of zero can come out as -0.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (Pyodide, QuickJS): nothing is sent to mysmartcopilot.com. The first run of each language downloads it: Python (about 13.5 MB) or JavaScript (about 0.6 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
Check yourself
6 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.
Interview questions
In Java, C++, Go and JavaScript, % can return a negative number. How do you get a remainder from 0 to m − 1,
and when does the common form ((a % m) + m) % m go wrong? There, % takes the sign of the dividend, so -7 % 3
is −1 rather than 2. Add m only when the remainder came out negative: r = a % m, then r += m if r < 0. At that
point r lies between −m and 0, so r + m lies between 0 and m and cannot overflow. Java’s Math.floorMod(a, m)
gives the same result for a positive m. The one-line form gives the same answers in exact arithmetic, but it adds m
to a remainder that may already be positive, so its sum can reach 2m − 2. For m = 10⁹ + 7 that still fits in a
32-bit int; once m is above 2³⁰ it does not, and Java returns −2,147,483,644 for a = 5 and m = 2,147,483,647.
JavaScript Numbers fail the same way for m above 2⁵², where the sum is rounded.
Besides addition and multiplication, which integer operations can overflow in a fixed-width type such as Java’s
int? Several that look harmless. Negating the most negative value overflows, because it has no positive
counterpart: in Java, -Integer.MIN_VALUE and Math.abs(Integer.MIN_VALUE) both return Integer.MIN_VALUE, which
is negative. Dividing that value by −1 overflows too: Java and Go define the quotient as the dividend itself, with a
remainder of 0, while in C++ both are undefined behaviour. Subtraction can overflow when the operands have opposite
signs, which breaks comparators written as a - b and midpoints written as a + (b - a) / 2. A left shift
multiplies by a power of two without any check, so 1 << 31 is −2,147,483,648 in a Java int. A narrowing cast
keeps only the low bits: (int) 3_000_000_000L is −1,294,967,296. Java’s Exact methods, such as negateExact,
absExact and toIntExact, throw an ArithmeticException in each of these cases instead.
Key takeaways
- Python floors a quotient; Java, C++, Go and JavaScript (with
Math.trunc) truncate it, and the remainder follows from a = q × b + r. The answers differ only when exactly one operand is negative. - For a remainder from 0 to m − 1, add m only when
a % mis negative, or useMath.floorModin Java. The one-line((a % m) + m) % moverflows once m is above half the type’s range. - Dividing the most negative value by −1 overflows: Java and Go return the dividend, and C++ leaves it undefined. Division by zero throws or panics everywhere except with JavaScript Numbers.
- In JavaScript, a remainder of zero can be
-0, whichconsole.logprints as-0. - Estimate the largest value from the limits before choosing a type, then check the risky operations: the
Exactmethods in Java, the overflow builtins and the sanitizer in C++, a limit test in Go,Number.isSafeIntegerin JavaScript. (a >> 1) + (b >> 1) + (a & b & 1)is a mean rounded down that never overflows;a + (b - a) / 2is safe only for values of one sign, such as indexes.- When an exact answer outgrows 64 bits, use
int,BigInt,BigIntegerorbig.Int; when only a remainder is asked for, stay with 64-bit integers and reduce after every step.
References
- The Python Language Reference: binary arithmetic operations (Python Software Foundation)
- The Python Standard Library: numeric types (int, float, complex) (Python Software Foundation)
- The Python Standard Library: bitwise operations on integer types (Python Software Foundation)
- ECMAScript 2026 Language Specification: Number::remainder (Ecma International)
- ECMAScript 2026 Language Specification: BigInt::divide and BigInt::remainder (Ecma International)
- ECMAScript 2026 Language Specification: Number.isSafeInteger (Ecma International)
- ECMAScript 2026 Language Specification: Number.MAX_SAFE_INTEGER (Ecma International)
- BigInt (MDN Web Docs)
- The Java Language Specification, Java SE 25: 15.17.2 Division Operator / (Oracle)
- The Java Language Specification, Java SE 25: 15.17.3 Remainder Operator % (Oracle)
- The Java Language Specification, Java SE 25: 15.19 Shift Operators (Oracle)
- The Java Language Specification, Java SE 25: 4.2.2 Integer Operations (Oracle)
- Java SE 25 API: java.lang.Math (floorDiv, floorMod, ceilDiv and the Exact methods) (Oracle)
- Java SE 25 API: java.math.BigInteger (Oracle)
- Working Draft, Programming Languages: C++ (N4950), [expr.mul] and [expr.shift] (ISO/IEC JTC1/SC22/WG21)
- Arithmetic operators (cppreference.com)
- std::midpoint (cppreference.com)
- UndefinedBehaviorSanitizer (The LLVM Project)
- Clang Language Extensions: checked arithmetic builtins (The LLVM Project)
- Using the GNU Compiler Collection: built-in functions to perform arithmetic with overflow checking (GNU Project (GCC))
- Using the GNU Compiler Collection: 128-bit integers (GNU Project (GCC))
- The Go Programming Language Specification: integer operators (The Go Authors)
- The Go Programming Language Specification: integer overflow (The Go Authors)
- Go standard library: package math/big (The Go Authors)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress