138 lines
3.1 KiB
Rexx
138 lines
3.1 KiB
Rexx
c1 = .complex~new(1, 2)
|
|
c2 = .complex~new(3, 4)
|
|
r = 7
|
|
|
|
say "c1 =" c1
|
|
say "c2 =" c2
|
|
say "r =" r
|
|
say "-c1 =" (-c1)
|
|
say "c1 + r =" c1 + r
|
|
say "c1 + c2 =" c1 + c2
|
|
say "c1 - r =" c1 - r
|
|
say "c1 - c2 =" c1 - c2
|
|
say "c1 * r =" c1 * r
|
|
say "c1 * c2 =" c1 * c2
|
|
say "inv(c1) =" c1~inv
|
|
say "conj(c1) =" c1~conjugate
|
|
say "c1 / r =" c1 / r
|
|
say "c1 / c2 =" c1 / c2
|
|
say "c1 == c1 =" (c1 == c1)
|
|
say "c1 == c2 =" (c1 == c2)
|
|
|
|
|
|
::class complex
|
|
::method init
|
|
expose r i
|
|
use strict arg r, i = 0
|
|
|
|
-- complex instances are immutable, so these are
|
|
-- read only attributes
|
|
::attribute r GET
|
|
::attribute i GET
|
|
|
|
::method negative
|
|
expose r i
|
|
return self~class~new(-r, -i)
|
|
|
|
::method add
|
|
expose r i
|
|
use strict arg other
|
|
if other~isa(.complex) then
|
|
return self~class~new(r + other~r, i + other~i)
|
|
else return self~class~new(r + other, i)
|
|
|
|
::method subtract
|
|
expose r i
|
|
use strict arg other
|
|
if other~isa(.complex) then
|
|
return self~class~new(r - other~r, i - other~i)
|
|
else return self~class~new(r - other, i)
|
|
|
|
::method times
|
|
expose r i
|
|
use strict arg other
|
|
if other~isa(.complex) then
|
|
return self~class~new(r * other~r - i * other~i, r * other~i + i * other~r)
|
|
else return self~class~new(r * other, i * other)
|
|
|
|
::method inv
|
|
expose r i
|
|
denom = r * r + i * i
|
|
return self~class~new(r/denom,-i/denom)
|
|
|
|
::method conjugate
|
|
expose r i
|
|
return self~class~new(r, -i)
|
|
|
|
::method divide
|
|
use strict arg other
|
|
-- this is easier if everything is a complex number
|
|
if \other~isA(.complex) then other = .complex~new(other)
|
|
-- division is multiplication with the inversion
|
|
return self * other~inv
|
|
|
|
::method "=="
|
|
expose r i
|
|
use strict arg other
|
|
|
|
if \other~isa(.complex) then return .false
|
|
-- Note: these are numeric comparisons, so we're using the "="
|
|
-- method so those are handled correctly
|
|
return r = other~r & i = other~i
|
|
|
|
::method "\=="
|
|
use strict arg other
|
|
return \self~"\=="(other)
|
|
|
|
::method "="
|
|
-- this is equivalent of "=="
|
|
forward message("==")
|
|
|
|
::method "\="
|
|
-- this is equivalent of "\=="
|
|
forward message("\==")
|
|
|
|
::method "<>"
|
|
-- this is equivalent of "\=="
|
|
forward message("\==")
|
|
|
|
::method "><"
|
|
-- this is equivalent of "\=="
|
|
forward message("\==")
|
|
|
|
-- some operator overrides -- these only work if the left-hand-side of the
|
|
-- subexpression is a quaternion
|
|
::method "*"
|
|
forward message("TIMES")
|
|
|
|
::method "/"
|
|
forward message("DIVIDE")
|
|
|
|
::method "-"
|
|
-- need to check if this is a prefix minus or a subtract
|
|
if arg() == 0 then
|
|
forward message("NEGATIVE")
|
|
else
|
|
forward message("SUBTRACT")
|
|
|
|
::method "+"
|
|
-- need to check if this is a prefix plus or an addition
|
|
if arg() == 0 then
|
|
return self -- we can return this copy since it is immutable
|
|
else
|
|
forward message("ADD")
|
|
|
|
::method string
|
|
expose r i
|
|
return r self~formatnumber(i)"i"
|
|
|
|
::method formatnumber private
|
|
use arg value
|
|
if value > 0 then return "+" value
|
|
else return "-" value~abs
|
|
|
|
-- override hashcode for collection class hash uses
|
|
::method hashCode
|
|
expose r i
|
|
return r~hashcode~bitxor(i~hashcode)
|