59 lines
1.7 KiB
Text
59 lines
1.7 KiB
Text
$define C = 7
|
|
|
|
class pt
|
|
static function zero() return new pt(math.inf, math.inf) end
|
|
|
|
static function from_num(n) return new pt(math.cbrt(n * n - C), n) end
|
|
|
|
function __construct(public x, public y) end
|
|
|
|
function iszero() return math.abs(self.x) > 1e20 end
|
|
|
|
function double()
|
|
if self:iszero() then return self end
|
|
local l = 3 * self.x * self.x / (2 * self.y)
|
|
local t = l * l - 2 * self.x
|
|
return new pt(t, l * (self.x - t) - self.y)
|
|
end
|
|
|
|
function __unm() return new pt(self.x, - self.y) end
|
|
|
|
function __add(other)
|
|
assert(other instanceof pt, "argument must be a pt object")
|
|
if self.x == other.x and self.y == other.y then return self:double() end
|
|
if self:iszero() then return other end
|
|
if other:iszero() then return self end
|
|
local l = (other.y - self.y) / (other.x - self.x)
|
|
local t = l * l - self.x - other.x
|
|
return new pt(t, l * (self.x - t) - self.y)
|
|
end
|
|
|
|
function __mul(n)
|
|
assert(math.type(n) == "integer", "argument must be an integer")
|
|
local r = pt.zero()
|
|
local p = self
|
|
local i = 1
|
|
while i <= n do
|
|
if (i & n) != 0 then r += p end
|
|
p = p:double()
|
|
i <<= 1
|
|
end
|
|
return r
|
|
end
|
|
|
|
function __tostring()
|
|
return self:iszero() ? "Zero" : string.format("(%0.3f, %0.3f)", self.x, self.y)
|
|
end
|
|
end
|
|
|
|
local a = pt.from_num(1)
|
|
local b = pt.from_num(2)
|
|
local c = a + b
|
|
local d = -c
|
|
print($"a = {a}")
|
|
print($"b = {b}")
|
|
print($"c = a + b = {c}")
|
|
print($"d = -c = {d}")
|
|
print($"c + d = {c + d}")
|
|
print($"a + b + d = {a + b + d}")
|
|
print($"a * 12345 = {a * 12345}")
|