Skip to content

Instantly share code, notes, and snippets.

@brilliant-ember
Last active May 23, 2026 10:09
Show Gist options
  • Select an option

  • Save brilliant-ember/a844599e3ad1066660e5c2d9e137af3f to your computer and use it in GitHub Desktop.

Select an option

Save brilliant-ember/a844599e3ad1066660e5c2d9e137af3f to your computer and use it in GitHub Desktop.
Big integer calculator in Go. It can handle integers of any size, even beyond 64 bits. Does Addition, Subtraction, Multiplication and Division (up to 10 decimal places accuracy)
package main
import (
"fmt"
"math/big"
"os"
"strings"
)
// Multiply returns the product of two integers as a *big.Int along with digit counts
func Multiply(a, b *big.Int) (*big.Int, int, int, int) {
product := new(big.Int).Mul(a, b)
return product, lenDigits(a), lenDigits(b), lenDigits(product)
}
// returns a string of the division
func Divide(a, b *big.Int) (string, int, int, int) {
r := new(big.Rat).SetFrac(a, b)
s := r.FloatString(10)
return s, lenDigits(a), lenDigits(b), countDigitsRat(s)
}
func Add(a, b *big.Int) (*big.Int, int, int, int) {
sum := new(big.Int).Add(a, b)
return sum, lenDigits(a), lenDigits(b), lenDigits(sum)
}
func Sub(a, b *big.Int) (*big.Int, int, int, int) {
s := new(big.Int).Sub(a, b)
return s, lenDigits(a), lenDigits(b), lenDigits(s)
}
// MultiplyStrings takes two string representations of integers and returns the product
func MultiplyStrings(aStr, bStr string) (*big.Int, int, int, int, error) {
a, b, err := stringToBigInt(aStr, bStr)
if err != nil {
return nil, 0, 0, 0, err
}
product, digitsA, digitsB, digitsProduct := Multiply(a, b)
return product, digitsA, digitsB, digitsProduct, nil
}
func DivideStrings(aStr, bStr string) (string, int, int, int, error) {
a, b, err := stringToBigInt(aStr, bStr)
if err != nil {
return "", 0, 0, 0, err
}
s, digitsA, digitsB, lenDiv := Divide(a, b)
return s, digitsA, digitsB, lenDiv, nil
}
func AddStrings(aStr, bStr string) (*big.Int, int, int, int, error) {
a, b, err := stringToBigInt(aStr, bStr)
if err != nil {
return nil, 0, 0, 0, err
}
sum, digitsA, digitsB, digitsProduct := Add(a, b)
return sum, digitsA, digitsB, digitsProduct, nil
}
func SubStrings(aStr, bStr string) (*big.Int, int, int, int, error) {
a, b, err := stringToBigInt(aStr, bStr)
if err != nil {
return nil, 0, 0, 0, err
}
s, digitsA, digitsB, digitsProduct := Sub(a, b)
return s, digitsA, digitsB, digitsProduct, nil
}
// MultiplyAndDisplay returns a formatted string with multiplication results
func MultiplyAndDisplay(aStr, bStr string) (string, error) {
product, digitsA, digitsB, digitsProduct, err := MultiplyStrings(aStr, bStr)
if err != nil {
return "", err
}
return fmt.Sprintf("%s (%d digits) × %s (%d digits) = %s (%d digits)",
aStr, digitsA, bStr, digitsB, product.String(), digitsProduct), nil
}
func DivideAndDisplay(aStr, bStr string) (string, error) {
d, digitsA, digitsB, lenD, err := DivideStrings(aStr, bStr)
if err != nil {
return "", err
}
return fmt.Sprintf("%s (%d digits) / %s (%d digits) = %s (%d digits)",
aStr, digitsA, bStr, digitsB, d, lenD), nil
}
func AddAndDisplay(aStr, bStr string) (string, error) {
sum, digitsA, digitsB, digitsSum, err := AddStrings(aStr, bStr)
if err != nil {
return "", err
}
return fmt.Sprintf("%s (%d digits) + %s (%d digits) = %s (%d digits)",
aStr, digitsA, bStr, digitsB, sum.String(), digitsSum), nil
}
func SubAndDisplay(aStr, bStr string) (string, error) {
s, digitsA, digitsB, digitsS, err := SubStrings(aStr, bStr)
if err != nil {
return "", err
}
return fmt.Sprintf("%s (%d digits) - %s (%d digits) = %s (%d digits)",
aStr, digitsA, bStr, digitsB, s.String(), digitsS), nil
}
func lenDigits(a *big.Int) int {
l := len(a.String())
if a.Sign() < 0 { // handle negative numbers
l = l - 1
}
return l
}
func stringToBigInt(aStr, bStr string) (*big.Int, *big.Int, error) {
a := new(big.Int)
b := new(big.Int)
aStr = strings.Replace(aStr, "_", "", -1)
aStr = strings.Replace(aStr, ",", "", -1)
bStr = strings.Replace(bStr, "_", "", -1)
bStr = strings.Replace(bStr, ",", "", -1)
_, ok1 := a.SetString(aStr, 10)
_, ok2 := b.SetString(bStr, 10)
if !ok1 || !ok2 {
return nil, nil, fmt.Errorf("invalid integer format: %s or %s", aStr, bStr)
}
return a, b, nil
}
func countDigitsRat(s string) int {
// trim trailing zeros
if strings.Contains(s, ".") {
s = strings.TrimRight(s, "0")
s = strings.TrimRight(s, ".") // remove dot if all decimals gone
}
// count digits only
count := 0
for _, c := range s {
if c >= '0' && c <= '9' {
count++
}
}
return count
}
func main() {
if len(os.Args) != 4 {
fmt.Printf("got %d args. Need 3 arguments: operation, num1, num2", len(os.Args)-1)
return
}
result := ""
var err error
switch strings.ToLower(os.Args[1]) {
case "add":
result, err = AddAndDisplay(os.Args[2], os.Args[3])
case "sub":
result, err = SubAndDisplay(os.Args[2], os.Args[3])
case "mul":
result, err = MultiplyAndDisplay(os.Args[2], os.Args[3])
case "div":
result, err = DivideAndDisplay(os.Args[2], os.Args[3])
default:
fmt.Printf("Error %s is not a known operation. You can choose either add, sub, mul, or div only", os.Args[1])
}
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
fmt.Println(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment