Langur has a complex number type, which is composed of two decimal numbers, representing the real and imaginary parts. These numbers have the same arbitrary precision (and benefits) as the number type.
A complex number literal contains an imaginary part. This may be specified with + (such as 3+3i) or - (such as 3-3i) or as a stand-alone imaginary number (such as 3i).
There is no imaginary number type. Thus, a stand-alone imaginary number is a complex number, with the real number part implied as 0.
Writing out a complex number literal may be affected by orders of operation. That is, 3+3i*3 is different than (3+3i)*3 because of precedence.
Besides complex literals, you can compose complex numbers using the complex() type conversion function.
Math operations do proper complex number operations. So, using abs() on a complex number is different than using it on a real number.
Operations between a complex and a real number convert the real number to a complex, with imaginary number implied as 0.
Results of math operations may be affected by the divMaxScale mode.
A complex conjugate can be obtained by splitting the complex number, negating the imaginary number, and putting it back together.
val conjugate = fn(c) { if c is not complex: throw "expected complex number" return complex(c[1], -c[2]) } writlne conjugate(1+1i) # result: 1-1i