# [Snippet] Complex Numbers

#### Malhorne

Level 18
Oh okay.
I fear that someone do this.
I think I'll fix those static to members.

#### looking_for_help

Level 14
Oh okay.
I fear that someone do this.
I think I'll fix those static to members.

Alright.

Btw it would be nice to make use of polar coordinates a bit more convenient for the user. At the moment one can only read out the polar values after the complex number was created in cartesian coordinates...

Suggestion: Add the following methods:

JASS:
``````// Constructor for a complex number from polar coordinates
static method createPolar takes real abs, real phase returns thistype

// Setter for absolute value of the complex number
method operator abs= takes real value returns nothing

// Setter for phase value of the complex number
method operator arg= takes real value returns nothing``````

This way both cartesian and polar form can be used in a uniform and convenient way.

EDIT:

You are missing a `call` here:

JASS:
``debug BJDebugMsg("thistype Error : Divide by 0!! Crashing thread")``

#### Malhorne

Level 18
I like your ideas.
Thanks for the bug founded ^^'
Such a shame to miss it.

But what to do if the user create a cartesian one and uses such method ?
It would be a mess.

#### looking_for_help

Level 14
But what to do if the user create a cartesian one and uses such method ?
It would be a mess.

Thats no problem at all.

It won't matter if the user used the cartesian constructor or the polar constructor, because internal the class will still only store the cartesian representation.

(One possible) sketch for setting the absolute value (or phase) of a cartesian Complex:

JASS:
``````1. Convert the cartesian to polar form
2. Set its absolute value/phase appropriate
3. Convert it back to cartesian and store those values``````

All nicely wrapped in the corresponding operator setters.

#### Malhorne

Level 18
Oh I see I didn't understand.

#### Malhorne

Level 18
Updated.
Didn't make the polar functions yet.

#### looking_for_help

Level 14
Updated.
Didn't make the polar functions yet.

Alright, looking forward for them.

You still have a call missing:

JASS:
``debug BJDebugMsg("thistype Error : Divide by 0!! Crashing thread")``

You could also make siginificantly decrease code size of the library if you use the constructor instead of allocate in your methods:

JASS:
``````method add takes thistype z returns thistype
local thistype c = thistype.allocate()
set c.re = this.re + z.re
set c.im = this.im + z.im
return c
endmethod``````

Can be rewriten as

JASS:
``````method add takes thistype z returns thistype
return thistype.create(this.re + z.re, this.im + z.im)
endmethod``````

Changing all methods like this will save quite some lines of code. Like you did for example in the exp method:

JASS:
``````method exp takes nothing returns thistype
return Complex.create(Pow(e, this.re)*Cos(this.im), Pow(e, this.re)*Sin(this.im))
endmethod``````

Although using `thistype` here would be preferable over `Complex`, to keep it consistent with the rest of the library.

#### Malhorne

Level 18
Yeah I just made this before seeing the post ^^'
I'll update soon.

Done.

#### looking_for_help

Level 14
Yeah I just made this before seeing the post ^^'
I'll update soon.

Done.

Nice, looks good. I will test it soon.

But you really don't like the call statement, right?

`debug BJDebugMsg("thistype Error : Divide by 0!! Crashing thread"`

still misses the call.

Level 18
Oh god.

#### looking_for_help

Level 14
This is getting really nice. However, there are still some things to improve.

Most important, the sqrt method is still not working 100%...

JASS:
``````local Complex c = Complex.create(-9, 0)
call BJDebugMsg(c.sqrt().toString())``````

Should display 0 + 3j (since thats the principal root of -9), but instead displays 0 + 0j.

Suggestions:

JASS:
``````method toString takes nothing returns string
local string s
if (this.im > 0) then
set s = R2S(this.re)+"+"+R2S(this.im)+"i"
else
set s = R2S(this.re)+" "+R2S(this.im)+"i"
endif
return s
endmethod``````

->

JASS:
``````method toString takes nothing returns string
if (this.im > 0) then
return R2S(this.re)+"+"+R2S(this.im)+"i"
endif
return R2S(this.re)+R2S(this.im)+"i" // No space required here
endmethod``````

Shorter and no temporary involved (the `div` method could also be shortened a bit by this). Also you should remove the space in the string for negative imaginary parts (see comment in the code above) such that both complex values look equal. Otherwise you have this:

JASS:
``````1.0-2.0i // good
1.0 +2.0i // additional space if im > 0, inconsistent``````

Minor Suggestions:

• Your private constants (like pi) could be capitalized (see coding conventions)
• Maybe a `toStringPolar` method would be nice too
• Add a check for the polar constructor and the operator abs setter if someone tries to set a negative abs value (since thats undefined).
• In the sqrt method change `this.im==0` to `this.im == 0` since you used spaces that way everywhere else to keep the coding consistent (same in `div` method).
• You have sometimes two newlines between methods (for example between operators abs and arg), that looks a bit strange

EDIT:

IMO it would also make sense to overload the equality operator (but not the smaller operator)

JASS:
``method operator== takes thistype z returns boolean``

such that complex values can be compared easier.

Last edited:

#### Malhorne

Level 18
I didn't remember it is possible to override == in vJASS.
Your suggestions look interesting.
Expect an update during the afternoon.

#### looking_for_help

Level 14
I didn't remember it is possible to override == in vJASS.

Well if I think a bit more about it, its maybe not a good idea to do this after all...

Basically there are two problems with this:

The first problem is that vJass is not typesafe when it comes to structs and people just use `thistype` interchangeable with `integer` instead of performing an explicit cast. So using an overloaded operator== might lead to difficult-to-find bugs.

The second problem is, that not all operators work. One can only define two operators, the rest is auto-generated (which would be a good thing in principal). The rules are like this:

• If you define `operator<`, then `operator>` is defined automatically
• If you define `operator==`, then `operator!=` is defined automatically

The problem is, that the operators `<=` and `>=` are never defined and you also have no way of defining these. So using them, will instead use the corresponding integer operators:

JASS:
``````struct Test
integer value
static method create takes integer val returns thistype
local thistype this = thistype.allocate()
set this.value = val
return this
endmethod
method operator< takes thistype other returns boolean
return value < other.value
endmethod
method operator== takes thistype other returns boolean
return value == other.value
endmethod
endstruct

function foo takes nothing returns nothing
Test t1 = Test.create(1)
Test t2 = Test.create(2)

if t1 == t2 then // calls Test.operator==
endif
if t1 > t2 then // calls Test.operator>
endif
if t1 >= t2 then // calls integer.operator>= !!!
endif
endfunction``````

Although this problem would not apply to a Complex class because a Complex does not have an operator< anyways, its maybe best to not allow these operators at all...

So, due to these problems I leave this point open for discussion and ask for some additional opinions.

#### Malhorne

Level 18
I think honestly that Complex comparaison could be interesting. Especially in the case when you compare polar declared and cartesian declared complex.
Overall it could be interesting even with this problem of typecast.

#### PurgeandFire

Level 43
I think it is fine to have an equality operator (==). It is commonplace for classes in general, even if they don't have a comparison operator (e.g. using hash values).

But I agree that with lfh, using comparator operators can lead to bugs that would be very difficult to debug. I suppose something like a compareTo() method could be implemented instead (negative => less than, 0 => equal, positive => greater than).

#### Malhorne

Level 18
Trying to sort C is pointless.
But yeah I agreee about the common point about comparaison operators.

#### looking_for_help

Level 14
Trying to sort C is pointless.
But yeah I agreee about the common point about comparaison operators.

Yes, maybe changing the `operator==` to a method like `equals` is better due to the incomplete implementation of operator overloading in vJass... I also seems that those operators don't work correctly when used in combination with modules, so... Maybe its best not to use them at all.

Btw, there seems to be an error in your div method:

JASS:
``````local Complex c1 = Complex.create(-81, 81)
local Complex c2 = Complex.create(-9, 0)
call BJDebugMsg(c1.div(c2).toString())``````

Should display 9.000 - 9.000i, but instead displays 9.000 - 729.000i, so there is something wrong.

My bad: in the toString method you should use `this.im >= 0` instead of `this.im > 0`, because zero is also displayed without sign, so we need to add the plus to the string as well.

Level 18
Updated

#### looking_for_help

Level 14

This is a high quality implementation of a complex numbers class that leaves basically no functionality to be desired. The coding is clean and efficient and the library uses a reasonable amount of code for its purpose.

Approved.

#### Malhorne

Level 18
I didn't expect such a sentence ^^
Anyway thanks for your time to improve this library.

#### edo494

Level 23
JASS:
``````*           method operator== takes thistype z returns boolean
*               ~ It returns if this==z or not``````

your method is called equals tho

Level 18
Woups ^^

#### Magtheridon96

Level 35
elitism at its prime?

So how would manderbrot usable in wc3 in any sensible way anyway?

It would be a demo!
Demos are not meant to be usable, they're just meant to showcase something.
The Mandelbrot set is a complex quadratic map, so it's an example of something you could implement using a library like this.

I didn't know making suggestions implies elitism.
Tell me more about your insights into the human condition.

#### edo494

Level 23
maybe you should also read the reply between 2 made by me on page 7, one of which you quoted

Replies
11
Views
2K
Replies
43
Views
5K
Replies
13
Views
2K
Replies
8
Views
2K
Replies
19
Views
9K