class num2 static function ipow(i, exp) assert(math.type(i) == "integer", "receiver must be an integer") assert(math.type(exp) == "integer", "exponent must be an integer") if i == 1 or exp == 0 then return 1 end if i == -1 then return exp % 2 == 0 ? 1 : -1 end assert(exp >= 0, "exponent cannot be negative for non-unit values") local ans = 1 local base = i local e = exp while e > 1 do if e % 2 == 1 then ans *= base end e //= 2 base *= base end return ans * base end static function fpow(f, exp) assert(type(f) == "number", "receiver must be a number") assert(math.type(exp) == "integer", "exponent must be an integer") local ans = 1.0 local e = exp local base = e < 0 ? 1 / f : f if e < 0 then e = -e end while e > 0 do if e % 2 == 1 then ans *= base end e //= 2 base *= base end return ans end public n function __construct(n) assert(type(n) == "number", "argument must be a number") self.n = n end -- Overloads '^' operator. function __pow(exp) assert(math.type(exp) == "integer", "exponent must be an integer") if math.type(n) == "integer" and (exp >= 0 or math.abs(self.n) == 1) then return num2.ipow(self.n, exp) else return num2.fpow(self.n, exp) end end end print("Using static methods:") print($" 2 ^ 3 = {num2.ipow( 2, 3)}") print($" 1 ^ -10 = {num2.ipow( 1, -10)}") print($" -1 ^ -3 = {num2.ipow(-1, -3)}") print() print($" 2.0 ^ -3 = {num2.fpow(2.0, -3)}") print($" 1.5 ^ 0 = {num2.fpow(1.5, 0)}") print($" 4.5 ^ 2 = {num2.fpow(4.5, 2)}") print("\nUsing the ^ operator:") print($" 2 ^ 3 = {new num2(2) ^ 3}") print($" 1 ^ -10 = {new num2(1) ^ -10}") print($" -1 ^ -3 = {new num2(-1) ^ -3}") print() print($" 2.0 ^ -3 = {new num2(2.0) ^ -3}") print($" 1.5 ^ 0 = {new num2(1.5) ^ 0}") print($" 4.5 ^ 2 = {new num2(4.5) ^ 2}")