Silent int/long overflow reproduced with real numbers, the Math *Exact() family (addExact/subtractExact/multiplyExact/incrementExact/decrementExact/ negateExact/toIntExact/absExact) with the abs(MIN_VALUE) trap absExact exists to catch, widening to long vs BigInteger, and the XOR-based overflow bit trick Math.addExact uses internally, cross-checked against BigInteger ground truth over 100k random int pairs per JUnit repeat. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01FhzLY5p6okFva3qsnsRyvM
48 lines
2.4 KiB
Markdown
48 lines
2.4 KiB
Markdown
# arithmetic
|
|
|
|
Companion code for the ankurm.com post *"Add Two Numbers in Java Without Overflow."* Eighth
|
|
module in `java-core-examples`.
|
|
|
|
`a + b` on two Java `int`s never throws when the true mathematical result doesn't fit - it wraps
|
|
around silently, two's-complement style. This module reproduces that wraparound with real
|
|
numbers, then works through every real fix: the `Math` class's `*Exact()` family (which throws
|
|
`ArithmeticException` instead of wrapping), widening to `long`, `BigInteger` for unbounded
|
|
precision, and the actual bit trick `Math.addExact` uses internally to detect overflow without
|
|
doing the addition twice at different widths.
|
|
|
|
## Versions this was built and tested against
|
|
|
|
| Component | Version | Notes |
|
|
|---|---|---|
|
|
| JDK | 25.0.4.1+1 (Temurin, LTS) | No preview flags needed - every API used here is finalized. |
|
|
| JUnit Jupiter | 5.11.0 | Includes a 100,000-iteration randomized cross-check per repeat. |
|
|
| Maven | 3.9.11 | |
|
|
| Hardware | 2 vCPU x86-64 VM | Same sandbox as the rest of this series. |
|
|
|
|
## Quickstart
|
|
|
|
```bash
|
|
export JAVA_HOME=/path/to/jdk-25
|
|
mvn package
|
|
java -cp target/classes com.ankurm.arithmetic.OverflowWrapDemo
|
|
java -cp target/classes com.ankurm.arithmetic.ExactArithmeticDemo
|
|
```
|
|
|
|
`scripts/run-all.sh` regenerates every file in `output/` (needs `JDK25_HOME`).
|
|
|
|
## What's in here
|
|
|
|
| File | What it shows |
|
|
|---|---|
|
|
| `.../OverflowWrapDemo.java` | `int` and `long` addition and multiplication wrapping silently past their max values - no exception, just a wrong answer. |
|
|
| `.../ExactArithmeticDemo.java` | The `Math` `*Exact()` family: `addExact`, `subtractExact`, `multiplyExact`, `incrementExact`, `decrementExact`, `negateExact`, `toIntExact`, `absExact` - normal case and overflow-throws case for each, plus the `Math.abs(Integer.MIN_VALUE)` trap that `absExact` exists to catch. |
|
|
| `.../WideningAndBigIntegerDemo.java` | Widening to `long` fixes the `int`-range overflow (but `long` can still overflow); `BigInteger` never overflows at all. |
|
|
| `.../OverflowBitTrickDemo.java` | The XOR-based overflow test for addition, cross-checked against `Math.addExact()` on the same inputs. |
|
|
| `src/test/.../ArithmeticClaimsTest.java` | Asserts every claim above, including a 100,000-sample-per-repeat randomized cross-check of the bit-trick detector against `BigInteger` ground truth. |
|
|
| `output/01`-`04` | Each demo's real run. |
|
|
| `output/05` | JUnit correctness run. |
|
|
|
|
## License
|
|
|
|
MIT - see the [repo-wide LICENSE](../LICENSE).
|