math, math/bits, and math/big
math, math/bits, and math/big
Overview
math: floating-point helpers (Sin,Sqrt,Inf,NaN, rounding).math/bits: integer bit operations (ones count, rotate, leading zeros)—often used for hashers, allocators, and compact encodings.math/big: arbitrary-precision integers/floats/rats—crypto sizes, money-like rationals, huge counters.
Most application code needs little of math; systems and crypto-adjacent tools use bits and big more.
math: floats with eyes open
import "math"
x := math.Hypot(3, 4) // 5
y := math.Round(2.5) // 3 (half away from zero in recent Go — check docs for edge cases)NaN and Inf
nan := math.NaN()
inf := math.Inf(1)
if math.IsNaN(nan) { /* ... */ }
if math.IsInf(inf, 1) { /* +Inf */ }NaN compares unequal to itself. Prefer math.IsNaN over ==.
Float equality
func almostEqual(a, b, eps float64) bool {
return math.Abs(a-b) <= eps
}Do not use == for computed floats in tests without a tolerance.
Integer-ish helpers
math.Max(a, b) // float64 only in classic math
// For ordered types prefer cmp / min/max builtins (Go 1.21+)
m := max(a, b) // builtin for integers etc.math/bits: integer bit tricks
import "math/bits"
bits.OnesCount64(x) // popcount
bits.LeadingZeros64(x) // for log2-ish sizing
bits.TrailingZeros64(x) // power-of-two alignment
bits.RotateLeft64(x, 7)
bits.ReverseBytes64(x)
bits.Len64(x) // bit lengthExample: next power of two sizing
func nextPow2(n uint64) uint64 {
if n <= 1 {
return 1
}
return 1 << bits.Len64(n-1)
}These compile to efficient CPU instructions on common architectures.
math/big: big integers
import "math/big"
a := new(big.Int).SetString("12345678901234567890", 10)
b := big.NewInt(42)
sum := new(big.Int).Add(a, b)
fmt.Println(sum.String())Methods mutate and return receiver
// sum = a + b; Add returns sum for chaining
sum.Add(a, b)
// careful: overlapping aliases — read docs for each methodModular exponent (crypto-shaped)
result := new(big.Int).Exp(base, exp, mod) // base^exp mod modFor production crypto, prefer crypto/* packages over hand-rolled big math.
Rationals and floats
r := big.NewRat(1, 3)
f, _ := new(big.Float).SetString("3.14159265358979323846")
_ = r
_ = fMoney warning
float64 is a poor ledger type. Prefer:
- integer cents (
int64), or big.Rat/ decimal libraries for fractional currency rules.
// cents
total := int64(1999) + int64(500) // $19.99 + $5.00Performance notes
| Tool | Cost |
|---|---|
math float ops |
Cheap; watch NaN paths |
math/bits |
Very cheap |
math/big |
Heap, slower; fine for rare big numbers |
Do not use big.Int for every loop counter.
Rules of thumb
| Do | Don’t |
|---|---|
Use builtins min/max for integers |
Force float math.Max for int |
| Test floats with epsilon | Assert exact binary equality |
Use bits for masks/popcount |
Hand-roll portable popcount |
Use big for true big integers |
Store money in float64 |
Try next
- Implement
nextPow2and table-test edges (0, 1, 2, 3, MaxUint32). - Add two 50-digit integers with
big.Int. - Show that
0.1+0.2 != 0.3in float64 and fix with integer cents.