Skip to content

Gustrb/checkedmath

Repository files navigation

checkedmath

Checked integer arithmetic for Go. Prevents overflow, underflow, and division by zero by returning errors instead of wrapping or panicking.

Installation

go get github.com/Gustrb/checkedmath

Requires Go 1.21+ (generics). Dependency: golang.org/x/exp (for constraints.Integer).

Quick start

Use the pre-bound functions for standard types:

package main

import (
	"fmt"
	"github.com/Gustrb/checkedmath"
)

func main() {
	// Addition — returns error on overflow
	sum, err := checkedmath.Add64(100, 200)
	if err != nil {
		fmt.Println("overflow:", err)
		return
	}
	fmt.Println(sum) // 300

	// Division by zero
	_, err = checkedmath.Div64(10, 0)
	if err != nil {
		fmt.Println(err) // division by zero
	}
}

Chain operations with the builder and check once at the end:

	result, err := checkedmath.NewInt64(10).
		Add(20).
		Mul(3).
		Div(2).
		Result()
	if err != nil {
		return err // overflow or division by zero
	}
	// result == 45

Supported types and operations

Type Add Sub Mul Div Builder Constructor
int8 Add8, Sub8, Mul8, Div8 BuilderInt8 NewInt8
int16 Add16, Sub16, Mul16, Div16 BuilderInt16 NewInt16
int32 Add32, Sub32, Mul32, Div32 BuilderInt32 NewInt32
int64 Add64, Sub64, Mul64, Div64 BuilderInt64 NewInt64
uint8 AddU8, SubU8, MulU8, DivU8 BuilderUint8 NewUint8
uint16 AddU16, SubU16, MulU16, DivU16 BuilderUint16 NewUint16
uint32 AddU32, SubU32, MulU32, DivU32 BuilderUint32 NewUint32
uint64 AddU64, SubU64, MulU64, DivU64 BuilderUint64 NewUint64
  • Add / Sub / Mul: return ErrOverflow when the result would exceed the type’s range (or underflow for unsigned Sub).
  • Div: returns ErrDivisionByZero when the divisor is zero.

Errors

  • checkedmath.ErrOverflow — result would overflow (or underflow for unsigned subtraction).
  • checkedmath.ErrDivisionByZero — division by zero.

Builder pattern

Builders let you chain operations and handle a single error at the end. After an error, later steps are no-ops and the same error is returned from Result().

	result, err := checkedmath.NewUint64(100).
		Mul(3).
		Div(2).
		DivRounded(7).
		Result()
  • DivRounded(n) — computes (value + n/2) / n (rounded division). Still returns ErrDivisionByZero if n == 0.

Custom bounds

For custom ranges (e.g. clamped values), use the generic constructors:

  • BoundedAdd[T](upper, lower T) func(a, b T) (T, error)
  • BoundedSub[T](upper, lower T) func(a, b T) (T, error)
  • BoundedMul[T](upper, lower T) func(a, b T) (T, error)
  • BoundedDiv[T](upper, lower T) func(a, b T) (T, error)

T must satisfy constraints.Integer. Example for int64 with standard range:

	add := checkedmath.BoundedAdd[int64](math.MaxInt64, math.MinInt64)
	sum, err := add(a, b)

License

See repository.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages