bigint

package module
v0.0.0-...-4670595 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: MIT Imports: 5 Imported by: 0

README

bigint

bigint provides an immutable-style arbitrary-precision integer type built on top of Go's math/big.Int.

It is intended for applications that need deterministic integer arithmetic, string-safe JSON encoding, SQL scanning, and protobuf-style binary marshaling without exposing mutable *big.Int values through the normal API.

Import path:

import "github.com/exc-works/bigint"

User Guides

Quick Start

package main

import (
	"fmt"

	"github.com/exc-works/bigint"
)

func main() {
	a := bigint.MustNewFromString("12345678901234567890")
	b := bigint.NewFromInt64(10)

	sum := a.Add(b)
	quotient := sum.Quo(bigint.NewFromInt(3), bigint.RoundDown)

	fmt.Println(a.String())        // 12345678901234567890
	fmt.Println(sum.String())      // 12345678901234567900
	fmt.Println(quotient.String()) // 4115226300411522633
}

Common values:

  • bigint.Zero
  • bigint.One
  • bigint.Ten

Core Design

BigInt uses value-style arithmetic:

  • methods like Add, Sub, Mul, Quo, Mod, Power, and Sqrt return new BigInt values
  • pointer receiver methods (Unmarshal*, Scan) update the receiver
  • BigInt() returns a defensive copy of the underlying math/big.Int

Example:

a := bigint.MustNewFromString("100")
b := a.Add(bigint.NewFromInt(23))

fmt.Println(a.String()) // 100  (a is unchanged)
fmt.Println(b.String()) // 123

Constructors

  • bigint.NewFromInt(int)
  • bigint.NewFromInt64(int64)
  • bigint.NewFromUint(uint)
  • bigint.NewFromUint64(uint64)
  • bigint.NewFromBigInt(*big.Int)
  • bigint.NewFromString(string) (bigint.BigInt, bool)
  • bigint.MustNewFromString(string)

NewFromString supports:

  • decimal strings: 123, -123
  • hexadecimal strings with 0x or 0X prefix
  • binary strings with 0b or 0B prefix

MustNewFromString panics when parsing fails, so use NewFromString for external input.

Arithmetic and Rounding

Arithmetic
  • Add(BigInt)
  • AddUint64(uint64)
  • AddInt64(int64)
  • Sub(BigInt)
  • Mul(BigInt)
  • Quo(BigInt, bigint.RoundingMode)
  • QuoDown(BigInt)
  • Mod(BigInt)
  • Power(int64)
  • Sqrt()
  • ShiftLeft(uint)
  • ShiftRight(uint)
Rounding Modes

Division supports these rounding modes:

  • bigint.RoundDown - toward zero
  • bigint.RoundUp - away from zero
  • bigint.RoundCeiling - toward positive infinity
  • bigint.RoundUnnecessary - panics if the quotient has a remainder

The enum also defines RoundHalfUp, RoundHalfDown, and RoundHalfEven for API compatibility, but integer division currently does not implement those modes.

Comparison
  • Cmp(BigInt)
  • Equal(BigInt)
  • GT(BigInt) / GTE(BigInt)
  • LT(BigInt) / LTE(BigInt)
  • package-level helpers: bigint.Max, bigint.Min
Sign and Conversion Helpers
  • Sign()
  • IsNil()
  • IsNegative()
  • IsZero()
  • IsPositive()
  • Neg()
  • Abs()
  • BitLen()
  • BigInt() *big.Int
  • GetInt64() int64

Serialization

String

String() implements fmt.Stringer. Uninitialized values render as "<nil>".

JSON
  • MarshalJSON() encodes initialized values as JSON strings
  • MarshalJSON() encodes an uninitialized value as null
  • UnmarshalJSON() accepts JSON strings and raw JSON numbers

Example:

type Balance struct {
	Amount bigint.BigInt `json:"amount"`
}
YAML

MarshalYAML() returns the string representation.

Binary / protobuf
  • MarshalBinary() / UnmarshalBinary()
  • Marshal() / Unmarshal()
  • MarshalTo([]byte)
  • Size()

Binary encoding delegates to math/big.Int gob encoding.

Database
  • Value() implements driver.Valuer
  • Scan(any) implements sql.Scanner

Scan supports nil, int64, uint64, string, and []byte.

Concurrency

Values returned by constructors and arithmetic methods are safe for concurrent read access as long as the variable itself is not being reassigned.

Pointer receiver methods mutate the receiver and require caller-side synchronization when a shared *BigInt may be accessed concurrently.

BigInt() returns a copy, so mutating the returned *big.Int does not affect the original BigInt.

Notes and Pitfalls

  • Prefer constructors over the zero value. The zero value is uninitialized, not numeric zero.
  • MustNewFromString panics on invalid input.
  • RoundUnnecessary panics if division is inexact.
  • Quo panics on unsupported rounding modes.
  • GetInt64() mirrors math/big.Int.Int64(): if the value does not fit in int64, the result is undefined.
  • NewFromBigInt wraps the supplied *big.Int; do not mutate that pointer afterwards unless you intentionally want shared state.

Release and Versioning

Example:

git tag -a v0.1.0 -m "release v0.1.0"
git push origin v0.1.0

License

MIT. See LICENSE.

Documentation

Overview

Package bigint provides an immutable-style arbitrary-precision integer type built on top of math/big.Int.

BigInt is useful when application code needs deterministic integer arithmetic, string-safe JSON encoding, SQL scanning, and binary marshaling while keeping the usual API surface free from mutable *big.Int receivers.

Value Semantics

Arithmetic and inspection methods have value receivers and return new BigInt values without mutating the receiver. Examples include Add, Sub, Mul, Quo, Mod, Power, Sqrt, Cmp, Sign, String, MarshalJSON, and MarshalBinary.

Methods with pointer receivers mutate the receiver and require external synchronization whenever the same *BigInt may be accessed by more than one goroutine. These include Scan, UnmarshalJSON, UnmarshalBinary, and Unmarshal.

Concurrency

A BigInt value created by a constructor or arithmetic method is safe for concurrent read access provided that no goroutine reassigns the variable holding it. Accessors that expose math/big values, such as BigInt, return defensive copies so callers can mutate the returned *big.Int without changing the original value.

Zero Value

The zero value of BigInt is uninitialized. Use Zero or NewFromInt(0) when a real numeric zero is required.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	Zero = NewFromInt(0)
	One  = NewFromInt(1)
	Ten  = NewFromInt(10)
)

Functions

func UnquoteIfQuoted

func UnquoteIfQuoted(value any) (string, error)

Types

type BigInt

type BigInt struct {
	// contains filtered or unexported fields
}

BigInt is a wrapper around big.Int that provides some convenience methods

Note: BigInt is immutable, so all methods return a new BigInt

Example (Arithmetic)
package main

import (
	"fmt"

	"github.com/exc-works/bigint"
)

func main() {
	a := bigint.MustNewFromString("12345678901234567890")
	b := bigint.NewFromInt64(10)

	sum := a.Add(b)
	quotient := sum.Quo(bigint.NewFromInt(3), bigint.RoundDown)

	fmt.Println(a)
	fmt.Println(sum)
	fmt.Println(quotient)

}
Output:
12345678901234567890
12345678901234567900
4115226300411522633
Example (Rounding)
package main

import (
	"fmt"

	"github.com/exc-works/bigint"
)

func main() {
	x := bigint.NewFromInt(-5)
	y := bigint.NewFromInt(2)

	fmt.Println(x.Quo(y, bigint.RoundDown))
	fmt.Println(x.Quo(y, bigint.RoundUp))
	fmt.Println(x.Quo(y, bigint.RoundCeiling))

}
Output:
-2
-3
-2

func Max

func Max(a, b BigInt) BigInt

func Min

func Min(a, b BigInt) BigInt

func MustNewFromString

func MustNewFromString(s string) BigInt

func NewFromBigInt

func NewFromBigInt(i *big.Int) BigInt

func NewFromInt

func NewFromInt(i int) BigInt

func NewFromInt64

func NewFromInt64(i int64) BigInt

func NewFromString

func NewFromString(s string) (BigInt, bool)

NewFromString returns a BigInt from a string.

If the string starts with 0x or 0X, it is interpreted as a hex string. If the string starts with 0b or 0B, it is interpreted as a binary string. Otherwise, it is interpreted as a decimal string.

func NewFromUint

func NewFromUint(i uint) BigInt

func NewFromUint64

func NewFromUint64(i uint64) BigInt

func (BigInt) Abs

func (b BigInt) Abs() BigInt

func (BigInt) Add

func (b BigInt) Add(b2 BigInt) BigInt

Add returns the sum of b and b2

func (BigInt) AddInt64

func (b BigInt) AddInt64(rhs int64) BigInt

AddInt64 returns the sum of b and rhs

func (BigInt) AddUint64

func (b BigInt) AddUint64(rhs uint64) BigInt

AddUint64 returns the sum of b and rhs

func (BigInt) BigInt

func (b BigInt) BigInt() *big.Int

BigInt returns a copy of the underlying big.Int.

func (BigInt) BitLen

func (b BigInt) BitLen() int

func (BigInt) Cmp

func (b BigInt) Cmp(b2 BigInt) int

func (BigInt) Equal

func (b BigInt) Equal(b2 BigInt) bool

func (BigInt) GT

func (b BigInt) GT(b2 BigInt) bool

func (BigInt) GTE

func (b BigInt) GTE(b2 BigInt) bool

func (BigInt) GetInt64

func (b BigInt) GetInt64() int64

GetInt64 returns the int64 representation of x. If x cannot be represented in an int64, the result is undefined.

func (BigInt) IsNegative

func (b BigInt) IsNegative() bool

func (BigInt) IsNil

func (b BigInt) IsNil() bool

func (BigInt) IsPositive

func (b BigInt) IsPositive() bool

func (BigInt) IsZero

func (b BigInt) IsZero() bool

func (BigInt) LT

func (b BigInt) LT(b2 BigInt) bool

func (BigInt) LTE

func (b BigInt) LTE(b2 BigInt) bool

func (BigInt) Marshal

func (b BigInt) Marshal() ([]byte, error)

Marshal implements the gogo proto custom type interface

func (BigInt) MarshalBinary

func (b BigInt) MarshalBinary() (data []byte, err error)

MarshalBinary implements the encoding.BinaryMarshaler interface

func (BigInt) MarshalJSON

func (b BigInt) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/exc-works/bigint"
)

func main() {
	type Balance struct {
		Amount bigint.BigInt `json:"amount"`
	}

	b := Balance{Amount: bigint.MustNewFromString("9007199254740993")}
	data, _ := json.Marshal(b)

	fmt.Println(string(data))

}
Output:
{"amount":"9007199254740993"}

func (BigInt) MarshalTo

func (b BigInt) MarshalTo(data []byte) (n int, err error)

MarshalTo implements the gogo proto custom type interface

func (BigInt) MarshalYAML

func (b BigInt) MarshalYAML() (any, error)

MarshalYAML implements the yaml.Marshaler interface

func (BigInt) Mod

func (b BigInt) Mod(b2 BigInt) BigInt

Mod returns the modulus b % b2

func (BigInt) Mul

func (b BigInt) Mul(b2 BigInt) BigInt

Mul returns the product of b and b2

func (BigInt) Neg

func (b BigInt) Neg() BigInt

func (BigInt) Power

func (b BigInt) Power(power int64) BigInt

Power returns a result of raising to integer power.

func (BigInt) Quo

func (b BigInt) Quo(b2 BigInt, roundingMode RoundingMode) BigInt

Quo returns the quotient of b and b2

Rounding mode is only support for math.RoundDown, math.RoundUp, math.RoundCeiling and math.RoundUnnecessary

func (BigInt) QuoDown

func (b BigInt) QuoDown(b2 BigInt) BigInt

QuoDown returns the quotient of b and b2

func (*BigInt) Scan

func (b *BigInt) Scan(value any) error

Scan implements the sql.Scanner interface

func (BigInt) ShiftLeft

func (b BigInt) ShiftLeft(n uint) BigInt

ShiftLeft returns b shifted left by n bits

func (BigInt) ShiftRight

func (b BigInt) ShiftRight(n uint) BigInt

ShiftRight returns b shifted right by n bits

func (BigInt) Sign

func (b BigInt) Sign() int

func (BigInt) Size

func (b BigInt) Size() int

Size implements the gogo proto custom type interface

func (BigInt) Sqrt

func (b BigInt) Sqrt() BigInt

Sqrt returns the square root of b

func (BigInt) String

func (b BigInt) String() string

String implements the fmt.Stringer interface

func (BigInt) Sub

func (b BigInt) Sub(b2 BigInt) BigInt

Sub returns the difference of b and b2

func (*BigInt) Unmarshal

func (b *BigInt) Unmarshal(data []byte) error

Unmarshal implements the gogo proto custom type interface

func (*BigInt) UnmarshalBinary

func (b *BigInt) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface

func (*BigInt) UnmarshalJSON

func (b *BigInt) UnmarshalJSON(bz []byte) error

UnmarshalJSON implements the json.Unmarshaler interface

func (BigInt) Value

func (b BigInt) Value() (driver.Value, error)

Value implements the driver.Valuer interface

type RoundingMode

type RoundingMode int
const (
	// RoundDown rounds towards zero.
	RoundDown RoundingMode = iota
	// RoundUp rounds away from zero.
	RoundUp
	// RoundCeiling rounds towards positive infinity.
	RoundCeiling
	// RoundHalfUp rounds to nearest; ties round up.
	RoundHalfUp
	// RoundHalfDown rounds to nearest; ties round down.
	RoundHalfDown
	// RoundHalfEven rounds to nearest; ties to even.
	RoundHalfEven
	// RoundUnnecessary asserts no rounding is required.
	RoundUnnecessary
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL