math_lib.sh

Download
bash 210 lines 4.6 KB
  1#!/usr/bin/env bash
  2set -euo pipefail
  3
  4# Math Library for Testing
  5# A collection of mathematical functions demonstrating testable bash code
  6# Can be sourced by other scripts or run standalone for demonstration
  7
  8# ============================================================================
  9# Basic Arithmetic Operations
 10# ============================================================================
 11
 12# Add two numbers
 13# Args: $1 - first number, $2 - second number
 14# Returns: sum of the two numbers
 15add() {
 16    local a=$1
 17    local b=$2
 18    echo $((a + b))
 19}
 20
 21# Subtract two numbers
 22# Args: $1 - first number, $2 - second number
 23# Returns: difference (first - second)
 24subtract() {
 25    local a=$1
 26    local b=$2
 27    echo $((a - b))
 28}
 29
 30# Multiply two numbers
 31# Args: $1 - first number, $2 - second number
 32# Returns: product of the two numbers
 33multiply() {
 34    local a=$1
 35    local b=$2
 36    echo $((a * b))
 37}
 38
 39# Divide two numbers
 40# Args: $1 - dividend, $2 - divisor
 41# Returns: quotient (integer division)
 42# Exits with error if divisor is zero
 43divide() {
 44    local a=$1
 45    local b=$2
 46
 47    if [[ $b -eq 0 ]]; then
 48        echo "Error: Division by zero" >&2
 49        return 1
 50    fi
 51
 52    echo $((a / b))
 53}
 54
 55# ============================================================================
 56# Advanced Mathematical Functions
 57# ============================================================================
 58
 59# Calculate factorial of a number
 60# Args: $1 - non-negative integer
 61# Returns: factorial of the number
 62factorial() {
 63    local n=$1
 64
 65    if [[ $n -lt 0 ]]; then
 66        echo "Error: Factorial not defined for negative numbers" >&2
 67        return 1
 68    fi
 69
 70    if [[ $n -eq 0 ]] || [[ $n -eq 1 ]]; then
 71        echo 1
 72        return 0
 73    fi
 74
 75    local result=1
 76    local i
 77    for ((i = 2; i <= n; i++)); do
 78        result=$((result * i))
 79    done
 80
 81    echo $result
 82}
 83
 84# Check if a number is prime
 85# Args: $1 - positive integer
 86# Returns: 0 (true) if prime, 1 (false) otherwise
 87is_prime() {
 88    local n=$1
 89
 90    if [[ $n -lt 2 ]]; then
 91        return 1
 92    fi
 93
 94    if [[ $n -eq 2 ]]; then
 95        return 0
 96    fi
 97
 98    if [[ $((n % 2)) -eq 0 ]]; then
 99        return 1
100    fi
101
102    local i
103    local sqrt_n=$(awk "BEGIN {print int(sqrt($n))}")
104
105    for ((i = 3; i <= sqrt_n; i += 2)); do
106        if [[ $((n % i)) -eq 0 ]]; then
107            return 1
108        fi
109    done
110
111    return 0
112}
113
114# Calculate greatest common divisor (GCD)
115# Args: $1 - first number, $2 - second number
116# Returns: GCD of the two numbers
117gcd() {
118    local a=${1#-}  # Remove negative sign if present
119    local b=${2#-}
120
121    while [[ $b -ne 0 ]]; do
122        local temp=$b
123        b=$((a % b))
124        a=$temp
125    done
126
127    echo $a
128}
129
130# Calculate least common multiple (LCM)
131# Args: $1 - first number, $2 - second number
132# Returns: LCM of the two numbers
133lcm() {
134    local a=${1#-}  # Remove negative sign if present
135    local b=${2#-}
136
137    if [[ $a -eq 0 ]] || [[ $b -eq 0 ]]; then
138        echo 0
139        return 0
140    fi
141
142    local gcd_val
143    gcd_val=$(gcd "$a" "$b")
144    echo $(( (a * b) / gcd_val ))
145}
146
147# ============================================================================
148# Demo Functions (only run when executed, not sourced)
149# ============================================================================
150
151demo_basic_operations() {
152    echo "=== Basic Arithmetic Operations ==="
153    echo "add 10 5 = $(add 10 5)"
154    echo "subtract 10 5 = $(subtract 10 5)"
155    echo "multiply 10 5 = $(multiply 10 5)"
156    echo "divide 10 5 = $(divide 10 5)"
157    echo
158}
159
160demo_advanced_functions() {
161    echo "=== Advanced Mathematical Functions ==="
162    echo "factorial 5 = $(factorial 5)"
163    echo "factorial 0 = $(factorial 0)"
164
165    if is_prime 17; then
166        echo "17 is prime"
167    else
168        echo "17 is not prime"
169    fi
170
171    if is_prime 20; then
172        echo "20 is prime"
173    else
174        echo "20 is not prime"
175    fi
176
177    echo "gcd 48 18 = $(gcd 48 18)"
178    echo "lcm 12 18 = $(lcm 12 18)"
179    echo
180}
181
182demo_error_handling() {
183    echo "=== Error Handling ==="
184    echo "Testing division by zero:"
185    if ! divide 10 0; then
186        echo "Correctly caught division by zero error"
187    fi
188
189    echo
190    echo "Testing negative factorial:"
191    if ! factorial -5; then
192        echo "Correctly caught negative factorial error"
193    fi
194    echo
195}
196
197# Main execution (only if script is run directly, not sourced)
198if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
199    echo "Math Library Demonstration"
200    echo "=========================="
201    echo
202
203    demo_basic_operations
204    demo_advanced_functions
205    demo_error_handling
206
207    echo "To use this library in other scripts, source it:"
208    echo "  source math_lib.sh"
209fi