Now for something completely different.
Imagine, you have an embedded system that does not support high level floating point operations such as sqrt(), sin(), ….. It only implements arithmetic operations such as +, -, *, /.
In this case, you‘ll need to implement those higher level functions yourself. I wrote a small calculator that implements high level functions based on arithmetic operations by using algorithms such as the Taylor series and the Newton-Ralphson method.
I also created the program, because I was interested in how calculators may implement these functions.
#Calculator
import math
class ScientificCalculator:
def __init__(self):
pass
def factorial(self, n):
if n == 0 or n == 1:
return 1
result = 1
for i in range(2, n + 1):
result *= i
return result
def power(self, base, exp):
# Handle fractional exponents
if exp < 0:
return 1 / self.power(base, -exp)
if isinstance(exp, float) and exp != int(exp):
numerator, denominator = self._fractional_parts(exp)
root = self.nth_root(base, denominator)
return self.power(root, numerator)
result = 1
for _ in range(abs(int(exp))):
result *= base
return result if exp >= 0 else 1 / result
def nth_root(self, x, n, iterations=10):
"""Calculate the nth root of x using Newton's method."""
if x < 0 and n % 2 == 0:
raise ValueError("Even roots of negative numbers are undefined.")
guess = x / n
for _ in range(iterations):
guess = ((n - 1) * guess + x / (guess ** (n - 1))) / n
return guess
def _fractional_parts(self, exp):
"""Split a fractional exponent into numerator and denominator."""
denominator = 10 ** len(str(exp).split(".")[1])
numerator = int(exp * denominator)
gcd = math.gcd(numerator, denominator)
return numerator // gcd, denominator // gcd
def taylor_sin(self, x, terms=10):
x = x % (2 * math.pi) # Normalize to [0, 2π]
result = 0
for n in range(terms):
term = self.power(-1, n) * self.power(x, 2 * n + 1) / self.factorial(2 * n + 1)
result += term
return result
def taylor_cos(self, x, terms=10):
x = x % (2 * math.pi) # Normalize to [0, 2π]
result = 0
for n in range(terms):
term = self.power(-1, n) * self.power(x, 2 * n) / self.factorial(2 * n)
result += term
return result
def taylor_exp(self, x, terms=10):
result = 0
for n in range(terms):
term = self.power(x, n) / self.factorial(n)
result += term
return result
def natural_log(self, x, terms=10):
if x <= 0:
raise ValueError("Logarithm undefined for non-positive values.")
if x == 1:
return 0
if x < 1:
x = 1 / x
invert = True
else:
invert = False
x -= 1
result = 0
for n in range(1, terms + 1):
term = self.power(-1, n + 1) * self.power(x, n) / n
result += term
return -result if invert else result
def square_root(self, x, iterations=10):
if x < 0:
raise ValueError("Square root undefined for negative values.")
guess = x / 2
for _ in range(iterations):
guess = (guess + x / guess) / 2
return guess
def calculate(self, operation, *args):
if operation == "sin":
return self.taylor_sin(args[0])
elif operation == "cos":
return self.taylor_cos(args[0])
elif operation == "exp":
return self.taylor_exp(args[0])
elif operation == "ln":
return self.natural_log(args[0])
elif operation == "sqrt":
return self.square_root(args[0])
elif operation == "power":
return self.power(args[0], args[1])
else:
raise ValueError("Unsupported operation.")
# Example usage
calc = ScientificCalculator()
print("0.5^1.5:", calc.calculate("power", 0.5, 1.5))
print("sin(π/2):", calc.calculate("sin", math.pi / 2))
print("cos(π):", calc.calculate("cos", math.pi))
print("exp(1):", calc.calculate("exp", 1))
print("ln(2):", calc.calculate("ln", 2))
print("sqrt(16):", calc.calculate("sqrt", 16))
print("2^3:", calc.calculate("power", 2, 3))
No comments:
Post a Comment