math, math/bits, and math/big

Updated

September 8, 2026

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 length

Example: 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 method

Modular exponent (crypto-shaped)

result := new(big.Int).Exp(base, exp, mod) // base^exp mod mod

For 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
_ = f

Money 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.00

Performance 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

  1. Implement nextPow2 and table-test edges (0, 1, 2, 3, MaxUint32).
  2. Add two 50-digit integers with big.Int.
  3. Show that 0.1+0.2 != 0.3 in float64 and fix with integer cents.