Last active
May 23, 2026 10:09
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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