Skip to content

dwisiswant0/safemath

Repository files navigation

safemath

tests Go Reference

safemath is a safe, generic, and robust integer math library for Go.

It provides overflow-safe arithmetic (+, -, *, /) and safe type conversions, preventing common bugs like overflow, underflow, and silent truncation that standard Go operations might miss.

Features

  • Comprehensive generics: works with all standard integer types.
  • Checked arithmetic: Add, Sub, Mul, Div functions return an error instead of allowing silent, dangerous wrapping.
  • Safe conversions: Convert[To, From](v) makes sure no data is lost during type conversion (e.g., checking bounds when casting larger types to smaller ones or signed to unsigned). ConvertAny extends the checks to any values, rejecting non-integer inputs.
  • Panic APIs: Must* variants are available for situations where panicking on failure is preferred.
  • Adversarial safety: robustly handles dangerous edge cases like $$MinInt / -1$$ and avoids hardware exceptions.

Usage

Installation

go get go.dw1.io/safemath

Basic Arithmetic

package main

import (
    "fmt"

    "go.dw1.io/safemath"
)

func main() {
    a, b := 100, 200

    // safe addition
    sum, err := safemath.Add(a, b)
    if err != nil {
        fmt.Println("Overflow:", err)
        return
    }
    fmt.Println("Sum:", sum)

    // safe multiplication
    prod, err := safemath.Mul(a, b)
    if err != nil {
        fmt.Println("Overflow:", err)
        return
    }

    fmt.Println("Product:", prod)
}

Converting from interface{}

val := any(int64(42))
out, err := safemath.ConvertAny[uint16](val)
if err != nil {
    fmt.Println(err)
}
fmt.Println(out)

// Will panic (ErrInvalidType) because input is not an integer
// _ = safemath.MustConvertAny[uint16]("nope")

Safe Conversion

package main

import (
    "fmt"

    "go.dw1.io/safemath"
)

func main() {
    var x int = 1000

    // converting large int to byte (should fail)
    val, err := safemath.Convert[byte](x)
    if err != nil {
        fmt.Printf("Conversion failed: %v\n", err) // Output: integer type truncation
    } else {
        fmt.Println("Converted:", val)
    }
}

Panic-on-Error (Must APIs)

package main

import (
    "go.dw1.io/safemath"
)

func main() {
    // will panic if overflow occurs
    sum := safemath.MustAdd(1, 2)
    println(sum)
}

Acknowledgements

This project is heavily inspired by trailofbits/go-panikint, a modified Go compiler that inserts automatic overflow checks at compile time.

safemath adopts a similar rigorous approach to correctness, throwing in:

  • Comprehensive edge cases: tested against the same critical boundaries (e.g., $$MinInt / -1$$) to make sure it's robust.
  • Truncation safety: Convert[To, From](v) logic mirrors the strict checking philosophy to prevent silent data loss during type conversion.

While Go-Panikint enforces safety via a custom compiler toolchain, safemath provides these same rigorous protections as a standard, zero-dependency, and portable Go library.

License

safemath is released with ♡ by @dwisiswant0 under the Apache 2.0 license. See LICENSE.

About

Safe, generic, and robust integer math library for Go.

Topics

Resources

License

Stars

Watchers

Forks

Contributors