📐 Bash Trigonometry & Math Functions

Comprehensive Reference Guide — Using bc, awk, and other tools for advanced mathematics

📋 Table of Contents

Overview

Bash doesn't have built-in trigonometry, but bc -l and awk provide complete math libraries. This guide covers sine, cosine, tangent, inverse functions, logarithms, exponentials, and practical applications for system administration, data analysis, and scientific computing.

Primary Tools

bc -l: The -l flag loads the math library with sin, cos, atan, log, exp, and more. All trig functions use radians.

awk: Built-in math functions including sin, cos, atan2, log, exp, sqrt. Also uses radians.

Math Function Reference

bc Math Library Functions (bc -l)

FunctionDescriptionExampleResult
s(x)Sine (radians)s(1.5708)≈ 1
c(x)Cosine (radians)c(0)1
a(x)Arctangent (radians)a(1)≈ 0.7854 (π/4)
l(x)Natural logarithm (ln)l(2.718)≈ 1
e(x)Exponential (e^x)e(1)≈ 2.718
sqrt(x)Square rootsqrt(16)4
j(n,x)Bessel functionj(0,1)≈ 0.7652
⚠️ Radians vs Degrees
All trig functions in bc and awk use radians, not degrees.
To convert: radians = degrees × π / 180
π can be calculated as: 4 * a(1) in bc

awk Math Functions

FunctionDescriptionExample
sin(x)Sine (radians)sin(3.14159/2)
cos(x)Cosine (radians)cos(0)
atan2(y,x)Arctangent of y/xatan2(1,1)
exp(x)Exponential (e^x)exp(1)
log(x)Natural logarithmlog(2.718)
sqrt(x)Square rootsqrt(2)
int(x)Integer partint(3.7)
rand()Random 0-1rand()

Derived Functions

These functions aren't built-in but can be derived:

Functionbc Formulaawk Formula
Tangents(x)/c(x)sin(x)/cos(x)
Arcsinea(x/sqrt(1-x*x))atan2(x,sqrt(1-x*x))
Arccosinea(sqrt(1-x*x)/x)atan2(sqrt(1-x*x),x)
Log base 10l(x)/l(10)log(x)/log(10)
Log base nl(x)/l(n)log(x)/log(n)
Power (x^y)e(y*l(x))x^y or exp(y*log(x))

Quick Reference: Constants

π = 4*a(1) in bc = 3.14159265...
e = e(1) in bc = 2.71828182...
π = atan2(0,-1) in awk

Trigonometry & Math Examples

1
Basic Trigonometric Functions with bc

Fundamental trig operations using bc's math library, including sine, cosine, and tangent.

#!/bin/bash
# Basic trig functions with bc -l

echo "=== Constants ==="
pi=$(echo "scale=10; 4*a(1)" | bc -l)
e=$(echo "scale=10; e(1)" | bc -l)
echo "π = $pi"
echo "e = $e"

echo ""
echo "=== Sine Function ==="
# sin(0) = 0, sin(π/2) = 1, sin(π) = 0
echo "sin(0) = $(echo "scale=6; s(0)" | bc -l)"
echo "sin(π/6) = $(echo "scale=6; s($pi/6)" | bc -l)"      # 0.5
echo "sin(π/4) = $(echo "scale=6; s($pi/4)" | bc -l)"      # √2/2 ≈ 0.707
echo "sin(π/2) = $(echo "scale=6; s($pi/2)" | bc -l)"      # 1
echo "sin(π) = $(echo "scale=6; s($pi)" | bc -l)"          # 0

echo ""
echo "=== Cosine Function ==="
echo "cos(0) = $(echo "scale=6; c(0)" | bc -l)"            # 1
echo "cos(π/3) = $(echo "scale=6; c($pi/3)" | bc -l)"      # 0.5
echo "cos(π/2) = $(echo "scale=6; c($pi/2)" | bc -l)"      # 0
echo "cos(π) = $(echo "scale=6; c($pi)" | bc -l)"          # -1

echo ""
echo "=== Tangent Function ==="
# tan(x) = sin(x)/cos(x)
tan() {
    echo "scale=6; s($1)/c($1)" | bc -l
}
echo "tan(0) = $(tan 0)"
echo "tan(π/4) = $(tan "$pi/4")"                           # 1
echo "tan(π/3) = $(tan "$pi/3")"                           # √3 ≈ 1.732

echo ""
echo "=== Pythagorean Identity ==="
# sin²(x) + cos²(x) = 1
angle="$pi/6"
sin_sq=$(echo "scale=10; s($angle)^2" | bc -l)
cos_sq=$(echo "scale=10; c($angle)^2" | bc -l)
sum=$(echo "scale=10; $sin_sq + $cos_sq" | bc -l)
echo "sin²(π/6) + cos²(π/6) = $sum"
Output: === Constants === π = 3.1415926535 e = 2.7182818284 === Sine Function === sin(0) = 0 sin(π/6) = .500000 sin(π/4) = .707106 sin(π/2) = 1.000000 sin(π) = 0 === Cosine Function === cos(0) = 1.000000 cos(π/3) = .500000 cos(π/2) = 0 cos(π) = -1.000000 === Tangent Function === tan(0) = 0 tan(π/4) = 1.000000 tan(π/3) = 1.732050 === Pythagorean Identity === sin²(π/6) + cos²(π/6) = 1.0000000000
2
Degree/Radian Conversions

Converting between degrees and radians for practical trig calculations.

#!/bin/bash
# Degree and radian conversions

pi=$(echo "scale=10; 4*a(1)" | bc -l)

# Conversion functions
deg_to_rad() {
    echo "scale=10; $1 * $pi / 180" | bc -l
}

rad_to_deg() {
    echo "scale=10; $1 * 180 / $pi" | bc -l
}

echo "=== Degrees to Radians ==="
for deg in 0 30 45 60 90 180 270 360; do
    rad=$(deg_to_rad $deg)
    printf "%3d° = %s rad\n" $deg "$rad"
done

echo ""
echo "=== Radians to Degrees ==="
echo "π/6 rad = $(rad_to_deg "$pi/6")°"
echo "π/4 rad = $(rad_to_deg "$pi/4")°"
echo "π/2 rad = $(rad_to_deg "$pi/2")°"
echo "π rad = $(rad_to_deg "$pi")°"
echo "2π rad = $(rad_to_deg "2*$pi")°"

echo ""
echo "=== Trig with Degrees ==="
# sin(30°) = 0.5
sin_deg() {
    local rad=$(deg_to_rad $1)
    echo "scale=6; s($rad)" | bc -l
}

cos_deg() {
    local rad=$(deg_to_rad $1)
    echo "scale=6; c($rad)" | bc -l
}

echo "sin(30°) = $(sin_deg 30)"
echo "sin(45°) = $(sin_deg 45)"
echo "sin(90°) = $(sin_deg 90)"
echo "cos(60°) = $(cos_deg 60)"
echo "cos(90°) = $(cos_deg 90)"

echo ""
echo "=== Common Angle Table ==="
printf "%-6s %-10s %-10s %-10s\n" "Deg" "Rad" "Sin" "Cos"
printf "%-6s %-10s %-10s %-10s\n" "---" "---" "---" "---"
for deg in 0 30 45 60 90; do
    rad=$(deg_to_rad $deg)
    sin=$(sin_deg $deg)
    cos=$(cos_deg $deg)
    printf "%-6s %-10.4f %-10s %-10s\n" "${deg}°" "$rad" "$sin" "$cos"
done
Output: === Degrees to Radians === 0° = 0 rad 30° = .5235987755 rad 45° = .7853981633 rad 60° = 1.0471975511 rad 90° = 1.5707963267 rad 180° = 3.1415926535 rad === Trig with Degrees === sin(30°) = .500000 sin(45°) = .707106 sin(90°) = 1.000000 cos(60°) = .500000 cos(90°) = 0 === Common Angle Table === Deg Rad Sin Cos --- --- --- --- 0° 0.0000 0 1.000000 30° 0.5236 .500000 .866025 45° 0.7854 .707106 .707106 60° 1.0472 .866025 .500000 90° 1.5708 1.000000 0
radians = degrees × π / 180
degrees = radians × 180 / π
3
Inverse Trigonometric Functions

Arcsine, arccosine, and arctangent for finding angles from ratios.

#!/bin/bash
# Inverse trig functions

pi=$(echo "scale=10; 4*a(1)" | bc -l)

# bc only has a(x) for arctangent
# We derive arcsin and arccos

# arcsin(x) = atan(x / sqrt(1 - x²))
arcsin() {
    echo "scale=10; a($1/sqrt(1-$1*$1))" | bc -l
}

# arccos(x) = atan(sqrt(1 - x²) / x)
arccos() {
    if (( $(echo "$1 > 0" | bc -l) )); then
        echo "scale=10; a(sqrt(1-$1*$1)/$1)" | bc -l
    else
        echo "scale=10; $pi + a(sqrt(1-$1*$1)/$1)" | bc -l
    fi
}

# arctan is built-in as a(x)
arctan() {
    echo "scale=10; a($1)" | bc -l
}

rad_to_deg() {
    echo "scale=4; $1 * 180 / $pi" | bc -l
}

echo "=== Arctangent ==="
echo "atan(0) = $(arctan 0) rad = $(rad_to_deg $(arctan 0))°"
echo "atan(1) = $(arctan 1) rad = $(rad_to_deg $(arctan 1))°"
echo "atan(√3) = $(arctan "sqrt(3)") rad = $(rad_to_deg $(arctan "sqrt(3)"))°"

echo ""
echo "=== Arcsine ==="
echo "asin(0) = $(arcsin 0) rad = $(rad_to_deg $(arcsin 0))°"
echo "asin(0.5) = $(arcsin 0.5) rad = $(rad_to_deg $(arcsin 0.5))°"
echo "asin(√2/2) = $(arcsin "sqrt(2)/2") rad = $(rad_to_deg $(arcsin "sqrt(2)/2"))°"
echo "asin(1) = $(arcsin 0.9999999) rad ≈ 90°"

echo ""
echo "=== Arccosine ==="
echo "acos(1) = $(arccos 1) rad = $(rad_to_deg $(arccos 1))°"
echo "acos(0.5) = $(arccos 0.5) rad = $(rad_to_deg $(arccos 0.5))°"
echo "acos(0) = $(echo "scale=10; $pi/2" | bc -l) rad = 90°"

echo ""
echo "=== Practical: Finding Angles ==="
# Given opposite=3, adjacent=4, find angle
opp=3
adj=4
angle_rad=$(arctan "$opp/$adj")
angle_deg=$(rad_to_deg $angle_rad)
echo "Triangle: opposite=$opp, adjacent=$adj"
echo "Angle = atan($opp/$adj) = $angle_deg°"

# Verify with hypotenuse
hyp=$(echo "scale=6; sqrt($opp^2 + $adj^2)" | bc -l)
echo "Hypotenuse = $hyp"
echo "sin(angle) = $opp/$hyp = $(echo "scale=6; $opp/$hyp" | bc -l)"
Output: === Arctangent === atan(0) = 0 rad = 0° atan(1) = .7853981633 rad = 45.0000° atan(√3) = 1.0471975511 rad = 60.0000° === Arcsine === asin(0) = 0 rad = 0° asin(0.5) = .5235987755 rad = 30.0000° asin(√2/2) = .7853981633 rad = 45.0000° asin(1) = 1.5707963267 rad ≈ 90° === Arccosine === acos(1) = 0 rad = 0° acos(0.5) = 1.0471975511 rad = 60.0000° acos(0) = 1.5707963267 rad = 90° === Practical: Finding Angles === Triangle: opposite=3, adjacent=4 Angle = atan(3/4) = 36.8698° Hypotenuse = 5.000000 sin(angle) = 3/5 = .600000
4
Logarithmic and Exponential Functions

Natural logarithm, common logarithm (base 10), and exponential functions for scientific calculations.

#!/bin/bash
# Logarithms and exponentials

echo "=== Natural Logarithm (ln) ==="
echo "ln(1) = $(echo "scale=6; l(1)" | bc -l)"
echo "ln(e) = $(echo "scale=6; l(e(1))" | bc -l)"
echo "ln(2) = $(echo "scale=6; l(2)" | bc -l)"
echo "ln(10) = $(echo "scale=6; l(10)" | bc -l)"

echo ""
echo "=== Exponential (e^x) ==="
echo "e^0 = $(echo "scale=6; e(0)" | bc -l)"
echo "e^1 = $(echo "scale=6; e(1)" | bc -l)"
echo "e^2 = $(echo "scale=6; e(2)" | bc -l)"
echo "e^-1 = $(echo "scale=6; e(-1)" | bc -l)"

echo ""
echo "=== Log Base 10 ==="
# log₁₀(x) = ln(x) / ln(10)
log10() {
    echo "scale=6; l($1)/l(10)" | bc -l
}

echo "log₁₀(1) = $(log10 1)"
echo "log₁₀(10) = $(log10 10)"
echo "log₁₀(100) = $(log10 100)"
echo "log₁₀(1000) = $(log10 1000)"

echo ""
echo "=== Log Base 2 ==="
log2() {
    echo "scale=6; l($1)/l(2)" | bc -l
}

echo "log₂(1) = $(log2 1)"
echo "log₂(2) = $(log2 2)"
echo "log₂(8) = $(log2 8)"
echo "log₂(1024) = $(log2 1024)"

echo ""
echo "=== Arbitrary Base Power ==="
# x^y = e^(y * ln(x))
power() {
    echo "scale=6; e($2 * l($1))" | bc -l
}

echo "2^10 = $(power 2 10)"
echo "10^3 = $(power 10 3)"
echo "2^0.5 = $(power 2 0.5)"    # √2
echo "e^π = $(power "e(1)" "4*a(1)")"

echo ""
echo "=== Practical: Decibel Calculations ==="
# dB = 10 * log₁₀(P₂/P₁)
p1=1
p2=100
db=$(echo "scale=2; 10 * $(log10 "$p2/$p1")" | bc -l)
echo "Power ratio $p2:$p1 = ${db} dB"

# Reverse: ratio from dB
db_val=20
ratio=$(echo "scale=4; e($db_val/10 * l(10))" | bc -l)
echo "${db_val} dB = ratio of $ratio"
Output: === Natural Logarithm (ln) === ln(1) = 0 ln(e) = 1.000000 ln(2) = .693147 ln(10) = 2.302585 === Exponential (e^x) === e^0 = 1.000000 e^1 = 2.718281 e^2 = 7.389056 e^-1 = .367879 === Log Base 10 === log₁₀(1) = 0 log₁₀(10) = 1.000000 log₁₀(100) = 2.000000 log₁₀(1000) = 3.000000 === Log Base 2 === log₂(1) = 0 log₂(2) = 1.000000 log₂(8) = 3.000000 log₂(1024) = 10.000000 === Arbitrary Base Power === 2^10 = 1024.000000 10^3 = 1000.000000 2^0.5 = 1.414213 === Practical: Decibel Calculations === Power ratio 100:1 = 20.00 dB 20 dB = ratio of 100.0000
logb(x) = ln(x) / ln(b)
xy = ey·ln(x)
5
Trigonometry with awk

Using awk's built-in math functions for trig calculations in data processing.

#!/bin/bash
# Trigonometry with awk

echo "=== Basic awk Trig ==="
awk 'BEGIN {
    pi = atan2(0, -1)
    print "π =", pi
    print ""
    
    print "sin(0) =", sin(0)
    print "sin(π/2) =", sin(pi/2)
    print "cos(0) =", cos(0)
    print "cos(π) =", cos(pi)
}'

echo ""
echo "=== awk Angle Table ==="
awk 'BEGIN {
    pi = atan2(0, -1)
    printf "%-8s %-10s %-10s %-10s\n", "Degrees", "Radians", "Sin", "Cos"
    printf "%-8s %-10s %-10s %-10s\n", "-------", "-------", "---", "---"
    
    for (deg = 0; deg <= 90; deg += 15) {
        rad = deg * pi / 180
        printf "%-8d %-10.4f %-10.4f %-10.4f\n", deg, rad, sin(rad), cos(rad)
    }
}'

echo ""
echo "=== atan2 Function ==="
# atan2(y, x) handles all quadrants correctly
awk 'BEGIN {
    pi = atan2(0, -1)
    
    print "atan2(1, 1) =", atan2(1, 1) * 180/pi, "degrees"      # 45°
    print "atan2(1, -1) =", atan2(1, -1) * 180/pi, "degrees"    # 135°
    print "atan2(-1, -1) =", atan2(-1, -1) * 180/pi, "degrees"  # -135°
    print "atan2(-1, 1) =", atan2(-1, 1) * 180/pi, "degrees"    # -45°
}'

echo ""
echo "=== Process Data with Trig ==="
# Convert polar to cartesian
echo "5 30
10 45
15 60
20 90" | awk '
BEGIN {
    pi = atan2(0, -1)
    printf "%-6s %-8s %-10s %-10s\n", "r", "θ(deg)", "x", "y"
}
{
    r = $1
    theta_deg = $2
    theta_rad = theta_deg * pi / 180
    
    x = r * cos(theta_rad)
    y = r * sin(theta_rad)
    
    printf "%-6.1f %-8.1f %-10.4f %-10.4f\n", r, theta_deg, x, y
}'
Output: === Basic awk Trig === π = 3.14159 sin(0) = 0 sin(π/2) = 1 cos(0) = 1 cos(π) = -1 === awk Angle Table === Degrees Radians Sin Cos ------- ------- --- --- 0 0.0000 0.0000 1.0000 15 0.2618 0.2588 0.9659 30 0.5236 0.5000 0.8660 45 0.7854 0.7071 0.7071 60 1.0472 0.8660 0.5000 75 1.3090 0.9659 0.2588 90 1.5708 1.0000 0.0000 === atan2 Function === atan2(1, 1) = 45 degrees atan2(1, -1) = 135 degrees atan2(-1, -1) = -135 degrees atan2(-1, 1) = -45 degrees === Process Data with Trig === r θ(deg) x y 5.0 30.0 4.3301 2.5000 10.0 45.0 7.0711 7.0711 15.0 60.0 7.5000 12.9904 20.0 90.0 0.0000 20.0000
💡 atan2 vs atan
atan2(y, x) correctly handles all four quadrants and avoids division by zero. Always prefer it over simple arctangent.
6
Hyperbolic Functions

Hyperbolic sine, cosine, and tangent functions for engineering and physics applications.

#!/bin/bash
# Hyperbolic functions

# sinh(x) = (e^x - e^-x) / 2
sinh() {
    echo "scale=6; (e($1) - e(-$1)) / 2" | bc -l
}

# cosh(x) = (e^x + e^-x) / 2
cosh() {
    echo "scale=6; (e($1) + e(-$1)) / 2" | bc -l
}

# tanh(x) = sinh(x) / cosh(x)
tanh() {
    echo "scale=6; (e($1) - e(-$1)) / (e($1) + e(-$1))" | bc -l
}

echo "=== Hyperbolic Sine ==="
echo "sinh(0) = $(sinh 0)"
echo "sinh(1) = $(sinh 1)"
echo "sinh(2) = $(sinh 2)"

echo ""
echo "=== Hyperbolic Cosine ==="
echo "cosh(0) = $(cosh 0)"
echo "cosh(1) = $(cosh 1)"
echo "cosh(2) = $(cosh 2)"

echo ""
echo "=== Hyperbolic Tangent ==="
echo "tanh(0) = $(tanh 0)"
echo "tanh(1) = $(tanh 1)"
echo "tanh(2) = $(tanh 2)"
echo "tanh(10) = $(tanh 10)"  # Approaches 1

echo ""
echo "=== Hyperbolic Identity ==="
# cosh²(x) - sinh²(x) = 1
x=1.5
cosh_sq=$(echo "scale=10; ($(cosh $x))^2" | bc -l)
sinh_sq=$(echo "scale=10; ($(sinh $x))^2" | bc -l)
diff=$(echo "scale=10; $cosh_sq - $sinh_sq" | bc -l)
echo "cosh²($x) - sinh²($x) = $diff"

echo ""
echo "=== Inverse Hyperbolic (arcsinh) ==="
# arcsinh(x) = ln(x + sqrt(x² + 1))
arcsinh() {
    echo "scale=6; l($1 + sqrt($1^2 + 1))" | bc -l
}

echo "arcsinh(0) = $(arcsinh 0)"
echo "arcsinh(1) = $(arcsinh 1)"
echo "arcsinh(sinh(2)) = $(arcsinh $(sinh 2))"

echo ""
echo "=== Practical: Catenary Curve ==="
# y = a * cosh(x/a) - cable hanging under gravity
a=10  # Parameter
echo "Catenary (a=$a):"
for x in -20 -10 0 10 20; do
    y=$(echo "scale=4; $a * ($(cosh "$x/$a"))" | bc -l)
    printf "  x=%3d: y=%s\n" $x "$y"
done
Output: === Hyperbolic Sine === sinh(0) = 0 sinh(1) = 1.175201 sinh(2) = 3.626860 === Hyperbolic Cosine === cosh(0) = 1.000000 cosh(1) = 1.543080 cosh(2) = 3.762195 === Hyperbolic Tangent === tanh(0) = 0 tanh(1) = .761594 tanh(2) = .964027 tanh(10) = .999999 === Hyperbolic Identity === cosh²(1.5) - sinh²(1.5) = 1.0000000000 === Catenary Curve === Catenary (a=10): x=-20: y=37.6219 x=-10: y=15.4308 x= 0: y=10.0000 x= 10: y=15.4308 x= 20: y=37.6219
sinh(x) = (ex - e-x) / 2
cosh(x) = (ex + e-x) / 2
tanh(x) = sinh(x) / cosh(x)
7
Distance and Coordinate Calculations

Practical geometry calculations including distance, midpoint, and angle between points.

#!/bin/bash
# Distance and coordinate calculations

pi=$(echo "scale=10; 4*a(1)" | bc -l)

echo "=== Euclidean Distance ==="
# d = sqrt((x₂-x₁)² + (y₂-y₁)²)
distance() {
    local x1=$1 y1=$2 x2=$3 y2=$4
    echo "scale=6; sqrt(($x2-$x1)^2 + ($y2-$y1)^2)" | bc -l
}

echo "Distance (0,0) to (3,4) = $(distance 0 0 3 4)"
echo "Distance (1,2) to (4,6) = $(distance 1 2 4 6)"
echo "Distance (-1,-1) to (2,3) = $(distance -1 -1 2 3)"

echo ""
echo "=== 3D Distance ==="
distance3d() {
    local x1=$1 y1=$2 z1=$3 x2=$4 y2=$5 z2=$6
    echo "scale=6; sqrt(($x2-$x1)^2 + ($y2-$y1)^2 + ($z2-$z1)^2)" | bc -l
}

echo "Distance (0,0,0) to (1,2,2) = $(distance3d 0 0 0 1 2 2)"

echo ""
echo "=== Angle Between Points ==="
# θ = atan2(y₂-y₁, x₂-x₁)
angle_between() {
    local x1=$1 y1=$2 x2=$3 y2=$4
    awk -v x1="$x1" -v y1="$y1" -v x2="$x2" -v y2="$y2" '
    BEGIN {
        angle = atan2(y2-y1, x2-x1)
        print angle * 180 / atan2(0,-1)
    }'
}

echo "Angle from (0,0) to (1,1) = $(angle_between 0 0 1 1)°"
echo "Angle from (0,0) to (1,0) = $(angle_between 0 0 1 0)°"
echo "Angle from (0,0) to (0,1) = $(angle_between 0 0 0 1)°"

echo ""
echo "=== Polar to Cartesian ==="
polar_to_cart() {
    local r=$1 theta_deg=$2
    local theta_rad=$(echo "scale=10; $theta_deg * $pi / 180" | bc -l)
    local x=$(echo "scale=6; $r * c($theta_rad)" | bc -l)
    local y=$(echo "scale=6; $r * s($theta_rad)" | bc -l)
    echo "x=$x, y=$y"
}

echo "r=10, θ=30°: $(polar_to_cart 10 30)"
echo "r=5, θ=45°: $(polar_to_cart 5 45)"
echo "r=8, θ=60°: $(polar_to_cart 8 60)"

echo ""
echo "=== Cartesian to Polar ==="
cart_to_polar() {
    local x=$1 y=$2
    local r=$(echo "scale=6; sqrt($x^2 + $y^2)" | bc -l)
    local theta=$(awk -v x="$x" -v y="$y" 'BEGIN { print atan2(y,x) * 180 / atan2(0,-1) }')
    echo "r=$r, θ=${theta}°"
}

echo "(3, 4): $(cart_to_polar 3 4)"
echo "(5, 5): $(cart_to_polar 5 5)"
echo "(0, 10): $(cart_to_polar 0 10)"
Output: === Euclidean Distance === Distance (0,0) to (3,4) = 5.000000 Distance (1,2) to (4,6) = 5.000000 Distance (-1,-1) to (2,3) = 5.000000 === 3D Distance === Distance (0,0,0) to (1,2,2) = 3.000000 === Angle Between Points === Angle from (0,0) to (1,1) = 45° Angle from (0,0) to (1,0) = 0° Angle from (0,0) to (0,1) = 90° === Polar to Cartesian === r=10, θ=30°: x=8.660254, y=5.000000 r=5, θ=45°: x=3.535533, y=3.535533 r=8, θ=60°: x=4.000000, y=6.928203 === Cartesian to Polar === (3, 4): r=5.000000, θ=53.1301° (5, 5): r=7.071067, θ=45° (0, 10): r=10.000000, θ=90°
8
Haversine Formula: Geographic Distance

Calculate the great-circle distance between two points on Earth using latitude and longitude.

#!/bin/bash
# Haversine formula for geographic distance

# Earth's radius in kilometers
EARTH_RADIUS=6371

haversine() {
    local lat1=$1 lon1=$2 lat2=$3 lon2=$4
    
    awk -v lat1="$lat1" -v lon1="$lon1" -v lat2="$lat2" -v lon2="$lon2" -v R="$EARTH_RADIUS" '
    BEGIN {
        pi = atan2(0, -1)
        
        # Convert to radians
        lat1_r = lat1 * pi / 180
        lat2_r = lat2 * pi / 180
        dlat = (lat2 - lat1) * pi / 180
        dlon = (lon2 - lon1) * pi / 180
        
        # Haversine formula
        a = sin(dlat/2)^2 + cos(lat1_r) * cos(lat2_r) * sin(dlon/2)^2
        c = 2 * atan2(sqrt(a), sqrt(1-a))
        
        distance = R * c
        printf "%.2f", distance
    }'
}

echo "=== Great Circle Distances ==="
echo ""

# New York to London
ny_lat=40.7128; ny_lon=-74.0060
london_lat=51.5074; london_lon=-0.1278
dist=$(haversine $ny_lat $ny_lon $london_lat $london_lon)
echo "New York to London: $dist km"

# Los Angeles to Tokyo
la_lat=34.0522; la_lon=-118.2437
tokyo_lat=35.6762; tokyo_lon=139.6503
dist=$(haversine $la_lat $la_lon $tokyo_lat $tokyo_lon)
echo "Los Angeles to Tokyo: $dist km"

# Sydney to Cape Town
sydney_lat=-33.8688; sydney_lon=151.2093
cape_lat=-33.9249; cape_lon=18.4241
dist=$(haversine $sydney_lat $sydney_lon $cape_lat $cape_lon)
echo "Sydney to Cape Town: $dist km"

# Short distance: Binghamton to NYC
bing_lat=42.0987; bing_lon=-75.9180
nyc_lat=40.7128; nyc_lon=-74.0060
dist=$(haversine $bing_lat $bing_lon $nyc_lat $nyc_lon)
echo "Binghamton to NYC: $dist km ($(echo "scale=1; $dist * 0.621371" | bc) miles)"

echo ""
echo "=== Bearing Calculation ==="
# Initial bearing from point 1 to point 2
bearing() {
    local lat1=$1 lon1=$2 lat2=$3 lon2=$4
    
    awk -v lat1="$lat1" -v lon1="$lon1" -v lat2="$lat2" -v lon2="$lon2" '
    BEGIN {
        pi = atan2(0, -1)
        
        lat1_r = lat1 * pi / 180
        lat2_r = lat2 * pi / 180
        dlon = (lon2 - lon1) * pi / 180
        
        x = sin(dlon) * cos(lat2_r)
        y = cos(lat1_r) * sin(lat2_r) - sin(lat1_r) * cos(lat2_r) * cos(dlon)
        
        bearing = atan2(x, y) * 180 / pi
        # Normalize to 0-360
        bearing = (bearing + 360) % 360
        
        printf "%.1f", bearing
    }'
}

bear=$(bearing $ny_lat $ny_lon $london_lat $london_lon)
echo "Bearing NY → London: ${bear}°"
Output: === Great Circle Distances === New York to London: 5570.22 km Los Angeles to Tokyo: 8815.47 km Sydney to Cape Town: 11005.24 km Binghamton to NYC: 206.07 km (128.0 miles) === Bearing Calculation === Bearing NY → London: 51.2°
a = sin²(Δlat/2) + cos(lat₁) × cos(lat₂) × sin²(Δlon/2)
c = 2 × atan2(√a, √(1-a))
distance = R × c
9
Wave Functions and Oscillations

Generating sine waves, combining waves, and calculating oscillation parameters.

#!/bin/bash
# Wave functions and oscillations

pi=$(echo "scale=10; 4*a(1)" | bc -l)

echo "=== Simple Sine Wave ==="
# y = A * sin(2π * f * t + φ)
amplitude=5
frequency=2
phase=0

echo "A=$amplitude, f=$frequency Hz, φ=$phase"
echo "Time  Value"
for t in $(seq 0 0.1 1); do
    y=$(echo "scale=4; $amplitude * s(2 * $pi * $frequency * $t + $phase)" | bc -l)
    printf "%.1f   %7.4f\n" $t $y
done

echo ""
echo "=== ASCII Wave Plot ==="
awk 'BEGIN {
    pi = atan2(0, -1)
    amplitude = 10
    
    for (t = 0; t <= 2*pi; t += 0.2) {
        y = amplitude * sin(t)
        # Scale to 0-20 for display
        pos = int(y + amplitude + 0.5)
        
        printf "%6.2f |", t
        for (i = 0; i <= 20; i++) {
            if (i == 10) printf "|"
            else if (i == pos) printf "*"
            else printf " "
        }
        printf "\n"
    }
}'

echo ""
echo "=== Wave Superposition ==="
# Two waves with different frequencies
awk 'BEGIN {
    pi = atan2(0, -1)
    
    print "Combining f=1 Hz and f=3 Hz:"
    print "  t     y1      y2      sum"
    
    for (t = 0; t <= 1; t += 0.1) {
        y1 = sin(2 * pi * 1 * t)
        y2 = 0.5 * sin(2 * pi * 3 * t)
        sum = y1 + y2
        printf "%.1f  %6.3f  %6.3f  %6.3f\n", t, y1, y2, sum
    }
}'

echo ""
echo "=== Damped Oscillation ==="
# y = A * e^(-bt) * sin(ωt)
awk 'BEGIN {
    pi = atan2(0, -1)
    A = 10
    b = 0.5      # Damping factor
    omega = 2*pi  # Angular frequency
    
    print "Damped oscillation (A=10, b=0.5):"
    for (t = 0; t <= 5; t += 0.5) {
        y = A * exp(-b * t) * sin(omega * t)
        printf "t=%.1f: y=%7.3f\n", t, y
    }
}'
Output: === Simple Sine Wave === A=5, f=2 Hz, φ=0 Time Value 0.0 0.0000 0.1 2.9389 0.2 4.7553 0.3 4.0451 0.4 1.5451 0.5 -1.5451 ... === ASCII Wave Plot === 0.00 | |* 0.20 | | * 0.40 | | * ... 3.14 | | ... === Wave Superposition === Combining f=1 Hz and f=3 Hz: t y1 y2 sum 0.0 0.000 0.000 0.000 0.1 0.588 0.294 0.882 0.2 0.951 0.000 0.951 ... === Damped Oscillation === Damped oscillation (A=10, b=0.5): t=0.0: y= 0.000 t=0.5: y= 6.065 t=1.0: y= 0.000 t=1.5: y= -2.231 ...
10
Complete Math Library Script

A comprehensive bash math library with all trig and advanced functions.

#!/bin/bash
# Comprehensive math library

# Initialize constants
PI=$(echo "scale=15; 4*a(1)" | bc -l)
E=$(echo "scale=15; e(1)" | bc -l)

# ===== Trigonometric Functions =====
sin_deg() { echo "scale=${2:-6}; s($1 * $PI / 180)" | bc -l; }
cos_deg() { echo "scale=${2:-6}; c($1 * $PI / 180)" | bc -l; }
tan_deg() { echo "scale=${2:-6}; s($1*$PI/180)/c($1*$PI/180)" | bc -l; }

sin_rad() { echo "scale=${2:-6}; s($1)" | bc -l; }
cos_rad() { echo "scale=${2:-6}; c($1)" | bc -l; }
tan_rad() { echo "scale=${2:-6}; s($1)/c($1)" | bc -l; }

# ===== Inverse Trig =====
asin() { echo "scale=${2:-6}; a($1/sqrt(1-$1*$1))" | bc -l; }
acos() {
    if (( $(echo "$1 >= 0" | bc -l) )); then
        echo "scale=${2:-6}; a(sqrt(1-$1*$1)/$1)" | bc -l
    else
        echo "scale=${2:-6}; $PI + a(sqrt(1-$1*$1)/$1)" | bc -l
    fi
}
atan() { echo "scale=${2:-6}; a($1)" | bc -l; }

# ===== Logarithms =====
ln()    { echo "scale=${2:-6}; l($1)" | bc -l; }
log10() { echo "scale=${2:-6}; l($1)/l(10)" | bc -l; }
log2()  { echo "scale=${2:-6}; l($1)/l(2)" | bc -l; }
logn()  { echo "scale=${3:-6}; l($1)/l($2)" | bc -l; }  # log base n

# ===== Exponential =====
exp()   { echo "scale=${2:-6}; e($1)" | bc -l; }
pow()   { echo "scale=${3:-6}; e($2 * l($1))" | bc -l; }

# ===== Hyperbolic =====
sinh() { echo "scale=${2:-6}; (e($1) - e(-$1)) / 2" | bc -l; }
cosh() { echo "scale=${2:-6}; (e($1) + e(-$1)) / 2" | bc -l; }
tanh() { echo "scale=${2:-6}; (e($1) - e(-$1)) / (e($1) + e(-$1))" | bc -l; }

# ===== Utility =====
sqrt()  { echo "scale=${2:-6}; sqrt($1)" | bc -l; }
abs()   { echo "scale=${2:-6}; if ($1 < 0) -($1) else $1" | bc -l; }
deg_to_rad() { echo "scale=${2:-10}; $1 * $PI / 180" | bc -l; }
rad_to_deg() { echo "scale=${2:-6}; $1 * 180 / $PI" | bc -l; }

# ===== Demo =====
echo "===== Math Library Demo ====="
echo "Constants:"
echo "  π = $PI"
echo "  e = $E"

echo ""
echo "Trigonometry (degrees):"
echo "  sin(30°) = $(sin_deg 30)"
echo "  cos(60°) = $(cos_deg 60)"
echo "  tan(45°) = $(tan_deg 45)"

echo ""
echo "Inverse trig:"
echo "  asin(0.5) = $(rad_to_deg $(asin 0.5))°"
echo "  acos(0.5) = $(rad_to_deg $(acos 0.5))°"
echo "  atan(1) = $(rad_to_deg $(atan 1))°"

echo ""
echo "Logarithms:"
echo "  ln(e) = $(ln $E)"
echo "  log₁₀(100) = $(log10 100)"
echo "  log₂(1024) = $(log2 1024)"

echo ""
echo "Powers & Roots:"
echo "  2^10 = $(pow 2 10)"
echo "  √2 = $(sqrt 2)"
echo "  e^2 = $(exp 2)"

echo ""
echo "Hyperbolic:"
echo "  sinh(1) = $(sinh 1)"
echo "  cosh(1) = $(cosh 1)"
echo "  tanh(1) = $(tanh 1)"

echo ""
echo "===== End Demo ====="
Output: ===== Math Library Demo ===== Constants: π = 3.141592653589793 e = 2.718281828459045 Trigonometry (degrees): sin(30°) = .500000 cos(60°) = .500000 tan(45°) = 1.000000 Inverse trig: asin(0.5) = 30.0000° acos(0.5) = 60.0000° atan(1) = 45.0000° Logarithms: ln(e) = 1.000000 log₁₀(100) = 2.000000 log₂(1024) = 10.000000 Powers & Roots: 2^10 = 1024.000000 √2 = 1.414213 e^2 = 7.389056 Hyperbolic: sinh(1) = 1.175201 cosh(1) = 1.543080 tanh(1) = .761594 ===== End Demo =====

Best Practices & Reference

Key Points

✓ Do
✗ Avoid

Common Formulas

# Constants
pi=$(echo "scale=10; 4*a(1)" | bc -l)
e=$(echo "scale=10; e(1)" | bc -l)

# Degree/Radian conversion
rad=$(echo "scale=10; $deg * $pi / 180" | bc -l)
deg=$(echo "scale=10; $rad * 180 / $pi" | bc -l)

# Basic trig (radians)
sin=$(echo "scale=6; s($x)" | bc -l)
cos=$(echo "scale=6; c($x)" | bc -l)
tan=$(echo "scale=6; s($x)/c($x)" | bc -l)

# Inverse trig
atan=$(echo "scale=6; a($x)" | bc -l)
asin=$(echo "scale=6; a($x/sqrt(1-$x*$x))" | bc -l)

# Logarithms
ln=$(echo "scale=6; l($x)" | bc -l)
log10=$(echo "scale=6; l($x)/l(10)" | bc -l)

# Power
pow=$(echo "scale=6; e($y * l($x))" | bc -l)

# Distance
dist=$(echo "scale=6; sqrt(($x2-$x1)^2 + ($y2-$y1)^2)" | bc -l)

Useful Identities

IdentityFormula
Pythagoreansin²(x) + cos²(x) = 1
Double anglesin(2x) = 2·sin(x)·cos(x)
Half anglesin²(x/2) = (1 - cos(x))/2
Sumsin(a+b) = sin(a)cos(b) + cos(a)sin(b)
Hyperboliccosh²(x) - sinh²(x) = 1
Euler'se^(ix) = cos(x) + i·sin(x)
← Back to BashSpecial Index ↑ Back to EXPANDED