### Real numbers ℝ

Our regular, ordinary, everyday numbers are called real numbers. These include integers and decimals. You can visualize real numbers as existing along an infinite number line—with zero in the middle, positive numbers counting up forever to infinity on the right, and negative numbers doing the exact opposite on the left.

When a real number is multiplied by itself the product is always positive. For example, if we choose the number 2 we see that 2 × 2 = 4. Similarly, had we chosen the negative number -2, the product would still be positive because two negative numbers multiplied together also produce a positive result; -2 × -2 = 4. For brevity we could rewrite these equations as 22 = 4 and (-2)2 = 4, respectively.

The square root of a real number has two possible answers. The square root of 4, for example, is both 2 and -2 because both are solutions for x in the equation x = √4.

### Imaginary numbers 𝕀

But suppose we wanted to find the square root of a negative number. Is there any number that could solve for x in the equation x = √(-4)? Sadly, there is not. Or more precisely: there is not any real solution for the square root of a negative number.

In his 1991 address on “Creativity in Management”, Monty Python’s John Cleese articulates Edward de Bono’s concept of the intermediate impossible (32:06) as a useful stepping stone towards a novel and useful solution. Imaginary numbers might be considered an intermediate impossible. The symbol i is defined as the imaginary solution to the equation x = √(-1), therefore i2 = -1. With this imaginary device we now have a solution to the above equation x = √(-4) and that solution is 2i. (And also -2i, of course! We can indicate this “plus or minus” possibility as ±2i.) Let’s inspect this more closely.

𝒙 = √(-4)
𝒙 = √( 4 × -1)
𝒙 = √4 × √(-1)
𝒙 = ±2 × √(-1)
𝒙 = ±2 × i
𝒙 = ±2i

2i is an imaginary number that consists of a real number multiplier, 2, and our imaginary solution to √(-1), called i. Like real numbers, imaginary numbers also exist along an infinite number line. We plotted our real number line horizontally, so let’s plot our imaginary number line vertically.

### Complex numbers ℂ

We just saw that multiplying a real number by i yields an imaginary number. But what if you add a real number to an imaginary one? Things get complex. A complex number is a number that can be expressed in the form a + bi, where a is the real component and bi is the imaginary component. Some examples might be 1 + 2i or 3 - 4i.

This is what the ComplexNumber class was created to handle. Open up your JavaScript console and paste in the following:

var
cat = new Q.ComplexNumber( 1,  2 ),
dog = new Q.ComplexNumber( 3, -4 )

cat.toText()//  Returns '1 + 2i'
dog.toText()//  Returns '3 - 4i'

Now we have two variables, cat and dog, that we can operate with. As you might guess, ComplexNumber includes instance methods for common operations like addition, subtraction, multiplication, and division. Try the following lines individually in your JavaScript console:

cat.add( dog ).toText()     //  Returns  '4 - 2i'
cat.subtract( dog ).toText()//  Returns '-2 + 6i'
cat.multiply( dog ).toText()//  Returns '11 + 2i'
cat.divide( dog ).toText()  //  Returns '-0.2 + 0.4i'

We can now verify that i2 = -1.

var i = new Q.ComplexNumber( 0, 1 )

i.toText()//  Returns  'i'
i.power( 2 ).toText()//  Returns  '-1'

Operation functions on Q.ComplexNumber instances generally accept as arguments both sibling instances and pure Number instances, though the value returned is always an instance of Q.ComplexNumber.

### Constructor

ComplexNumber Function([ real: Number or Q.ComplexNumber ][, imaginary: Number ]]) => Q.ComplexNumber
Expects zero to two arguments. If the first argument is a ComplexNumber then that value is cloned and any remaining arguments are ignored. If either of the arguments are undefined they are assumed to be zero. If the first argument is not a ComplexNumber and either of the arguments are not number-like then an error is thrown.

var
ape = new Q.ComplexNumber(),
bee = new Q.ComplexNumber( 1 ),
elk = new Q.ComplexNumber( 1, 2 ),
fox = new Q.ComplexNumber( elk )

ape.toText()//  Returns '0'
bee.toText()//  Returns '1'
elk.toText()//  Returns '1 + 2i'
fox.toText()//  Returns '1 + 2i'

elk.isEqualTo( fox )   //  Returns true
elk.index === fox.index//  Returns false
• real
Number Traditionally the first argument, a number-like value representing the real component of the complex number.
• imaginary
Number Traditionally the second argument, a number-like value representing the imaginary component of the complex number.
• index
Number An identification number assigned to the instance, used for minding the total number of instances created.

### Static properties

• help
Function ⇒ String Calls and returns the value of Q.help, passing Q.ComplexNumber as the argument.
• index
Number The number of instances created so far.

#### Constants and constant creation

• constants
Object Constants are appended directly to the Q.ComplexNumber object. For convenience they are also appended to this Q.ComplexNumber.constants object to make looking up constants in the JavaScript console trivial, and to make iterating across all constants convenient via functions like Object.entries, Object.keys, Object.values, and so on. The intention that a property act as a constant is signaled by its labelling in all-uppercase.
• createConstant
Function( key: String, value: * ) Appends a property named by key with a value of value to both the Q object and its constants property.
• createConstants
Function( … ) Expects an even number of arguments. Will use each pair in the sequence of arguments to call createConstant.
• ZERO
Q.ComplexNumber Intialized as new Q.ComplexNumber( 0, 0 ). Described as 0.
• ONE
Q.ComplexNumber Intialized as new Q.ComplexNumber( 1, 0 ). Described as 1.
• E
Q.ComplexNumber Intialized as new Q.ComplexNumber( Math.E, 0 ). Described as e ≈ 2.7183.
• PI
Q.ComplexNumber Intialized as new Q.ComplexNumber( Math.PI, 0 ). Described as exactly equal to 3.
• I
Q.ComplexNumber Intialized as new Q.ComplexNumber( 0, 1 ). Described as i.
• EPSILON
Q.ComplexNumber Intialized as new Q.ComplexNumber( Q.EPSILON, Q.EPSILON ). Described as ≈ 1.3323 × 10-15 + 1.3323 × 10-15i.
• INFINITY
Q.ComplexNumber Intialized as new Q.ComplexNumber( Infinity, Infinity ). Described as + ∞i.
• NAN
Q.ComplexNumber Intialized as new Q.ComplexNumber( NaN, NaN ). Array( 16 ).join( NaN ) +' BATMAN!'

#### Inspection

• isNumberLike
Function( n: * ) ⇒ Boolean Returns true if n’s typeof is equal to the String 'number' or if n instanceof Number is true, otherwise returns false.
• isNaN
Function( c: Q.ComplexNumber ) ⇒ Boolean Returns true if either of this instance’s real or imaginary components are NaN, otherwise returns false.
• isZero
Function( c: Q.ComplexNumber ) ⇒ Boolean Returns true if both of this instance’s real and imaginary absolute values are equal to zero, otherwise returns false. See “Signed zero” for an explanation of why the absolute value of zero must be taken.
• isFinite
Function( c: Q.ComplexNumber ) ⇒ Boolean Returns true if both of this instance’s real and imaginary values are finite, otherwise returns false.
• isInfinite
Function( c: Q.ComplexNumber ) ⇒ Boolean Returns true if both of this instance’s real and imaginary values are not finite and are also not NaN, otherwise returns false.
• areEqual
Function( a: Number or Q.ComplexNumber, b: Number or Q.ComplexNumber ) ⇒ Boolean Returns true if the arguments a and b are within Q.EPSILON of each other, otherwise returns false.

#### Maths

• absolute
Function( c: Q.ComplexNumber ) ⇒ Number Calls and returns the value of Q.hypotenuse using c’s real and imaginary properties as arguments.
• conjugate
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns a new complex number with the values c.real and c.imaginary * -1.
• sine
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns the sine of c.
• cosine
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns the cosine of c.
• arcCosine
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns the arccosine of c.
• arcTangent
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns the arctangent of c.
• power
Function( a: Number or Q.ComplexNumber, b: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns a raised to the power of b.
• squareRoot
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns the square root of c.
• log
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Returns the log of c.
• operate
Function( name: String, a: Number or Q.ComplexNumber, b: Number or Q.ComplexNumber, numberAndNumber: Function, numberAndComplex: Function, complexAndNumber: Function, complexAndComplex: Function ) ⇒ * Meta function for performing operations on two values that may each be either numbers or complex numbers. The name argument indicates the name of the operation being performed and is used in error logging should the operation fail. The intent is to return a Q.ComplexNumber, though this is up to the functions passed in as it is their return values that are returned.
• multiply
Function( a: Number or Q.ComplexNumber, b: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Uses Q.ComplexNumber.operate to return the result of multiplying a and b.
• divide
Function( a: Number or Q.ComplexNumber, b: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Uses Q.ComplexNumber.operate to return the result of dividing a by b.
Function( a: Number or Q.ComplexNumber, b: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Uses Q.ComplexNumber.operate to return the result of adding a and b.
• subtract
Function( a: Number or Q.ComplexNumber, b: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Uses Q.ComplexNumber.operate to return the result of subtracting b from a.

### Prototype properties

• clone
Function ⇒ Q.ComplexNumber Returns a new instance with the values for real and imaginary copied from this instance.
• copy\$
Function( c: Q.ComplexNumber ) ⇒ Q.ComplexNumber Copies the values for real and imaginary from the supplied Q.ComplexNumber argument.

#### Maths (non-destructive)

• absolute
Function ⇒ Number Passes this instance as an argument to the absolute static method and returns the result. Will return a Number value, thereby halting “Fluent interface” method chaining for this instance.
• conjugate
Function ⇒ Q.ComplexNumber Passes this instance as an argument to the conjugate static method and returns the result.
• power
Function( n: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Passes this instance as the first argument and n as the second argument to the power static method and returns the result.
• squareRoot
Function ⇒ Q.ComplexNumber Passes this instance as an argument to the squareRoot static method and returns the result.
• log
Function ⇒ Q.ComplexNumber Passes this instance as an argument to the log static method and returns the result.
• multiply
Function( n: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Passes this instance as the first argument and n as the second argument to the multiply static method and returns the result.
• divide
Function( n: Number or Q.ComplexNumber ) ⇒ Q.ComplexNumber Passes this instance as the first argument and n as the second argument to the divide static method and returns the result.