Building an Arbitrary precision integer calculator in Golang

Introduction

Calculators are essential tools in our daily lives, whether for simple arithmetic or complex calculations. While standard calculators are limited by their precision and the size of numbers they can handle, an arbitrary precision calculator can manage extremely large numbers and perform arithmetic with precision beyond the constraints of standard data types.

This blog will take you through the creation of an Arbitrary Precision Calculator in Go, showcasing its features, code structure, and the logic behind its implementation. This project demonstrates the power of Go for handling computationally intensive tasks and its suitability for projects requiring high efficiency.


Features

  1. Arbitrary Precision Arithmetic:

    • Supports addition, subtraction, multiplication, and division of numbers with unlimited digits.

Project Structure

The project is organized into two main files:

  1. main.go: Handles user interaction and input parsing.

  2. number.go: Contains the core logic for arbitrary precision arithmetic.

Folder Structure

goCopy codecalc/
├── go.mod
├── main.go
└── number.go

Implementation

Core Logic in number.go

The number.go file contains the implementation of the BigNumber type and the functions for arithmetic operations.

1. Defining the BigNumber Type

type BigNumber struct {
    Digits []int // Stores the number in reverse order for easier arithmetic
    Base   int   // Base of the number (e.g., 10 for decimal)
}

The BigNumber type uses a slice to store digits in reverse order, simplifying operations like addition and multiplication.

2. Arithmetic Operations

  • Addition:

      func Add(a, b *BigNumber) *BigNumber {
          maxLength := max(len(a.Digits), len(b.Digits))
          result := make([]int, maxLength+1)
          carry := 0
    
          for i := 0; i < maxLength || carry != 0; i++ {
              sum := carry
              if i < len(a.Digits) {
                  sum += a.Digits[i]
              }
              if i < len(b.Digits) {
                  sum += b.Digits[i]
              }
              result[i] = sum % a.Base
              carry = sum / a.Base
          }
          return &BigNumber{Digits: trimLeadingZeros(result), Base: a.Base}
      }
    

    This method iterates over the digits of two numbers, adding them with a carry.

  • Subtraction, Multiplication, and Division: Each operation follows a similar principle, iterating over digits and performing calculations based on arithmetic rules.

3. Helper Functions

  • max: Finds the maximum of two integers.

  • trimLeadingZeros: Removes leading zeros from the result for cleaner output.


User Interface in main.go

The main.go file provides a command-line interface for interacting with the calculator.

1. Input Parsing

func processInput(input string) string {
    parts := strings.Fields(input)
    if len(parts) != 3 {
        return "Invalid input. Please provide two numbers and an operator."
    }

    number1 := NewBigNumber(parts[0], 10)
    number2 := NewBigNumber(parts[2], 10)
    operator := parts[1]

    switch operator {
    case "+":
        result := Add(number1, number2)
        return result.String()
    case "-":
        result := Subtract(number1, number2)
        return result.String()
    case "*":
        result := Multiply(number1, number2)
        return result.String()
    case "/":
        quotient, remainder := Divide(number1, number2)
        return fmt.Sprintf("Quotient: %s, Remainder: %s", quotient.String(), remainder.String())
    default:
        return "Invalid operator. Please use +, -, *, or /."
    }
}

This function parses user input, validates it, and calls the appropriate arithmetic function.

2. Main Function

 func main() {
    fmt.Println("Welcome to the Arbitrary Precision Calculator")
    fmt.Println("Input your calculations (e.g., '12345 + 67890') or type 'exit' to exit.")

    reader := bufio.NewReader(os.Stdin)

    for {
        fmt.Print(">>> ")
        input, _ := reader.ReadString('\n')
        input = strings.TrimSpace(input)

        if input == "exit" {
            fmt.Println("Goodbye!")
            break
        }

        result := processInput(input)
        fmt.Printf("Result: %s\n", result)
    }
}

This provides a user-friendly CLI for entering calculations.


How to Run the Project

1. Prerequisites

2. Clone the Repository

git clone <repository_url>
cd calc

3. Run the Program

go run main.go number.go || go run .

4. Example Usage

Input:

>>> 12345 + 67890

Output:

Result: 80235

Input:

>>> 1000 * 300

Output:

Result: 300000

Input:

>>> 789 / 12

Output:

Quotient: 65, Remainder: 9

Conclusion

This project demonstrates the power and flexibility of Go for creating efficient and scalable solutions. By building an Arbitrary Precision Calculator, we explored key programming concepts like data structures, arithmetic algorithms, and user interaction. Whether you're a beginner or an experienced developer, this project offers valuable insights into the world of precision arithmetic.

Happy coding! 🎉

My passion for computing

Computing as a field is a gateway to endless possibilities and the fact that solving real world problems through logic , innovation and as long as the problem can be written as an algorithm to solve is it is only limited by my imagination.

If I could meet any scientist

Nikola Tesla once said, "The present is theirs; the future, for which I really worked, is mine." This quote encapsulates his enduring influence. Tesla's genius lives on in every circuit, every electric motor, and every technology that powers our interconnected world.