- Joined
- Dec 12, 2012
- Messages
- 1,000
Keep seven digits, like in my Maths library.
Well, the link is that you use this in your resource:
private constant real e = 2.71828182845904523536028747135266249775724700000
This is bad and you shouldn't do that. However, the explanation why it is bad was incorrect. Its not slowing down your resource, but just making the variable to overflow and therefore store an undefined value.
As already mentioned, Wc3 reals are 32 bit floats. This datatype has seven significant digits, which means that if you put in more, it will overflow. Try this:
JASS:private static method onInit takes nothing returns nothing local real e = 2.71828182845904523536028747135266249775724700000 call BJDebugMsg(R2S(e*e)) endmethod
For me, it outputs 4.00, while the correct result should be about 7.38.
Thats the reason why I use in my Maths library the constantreal E = 2.718282
(seven digits). It is a bit more accurate than the native Jass constant for e,bj_E
(six digits), thats why I included that constant in the Maths library. Higher accuracy is not possible with 32 bit floating numbers.
If you want to use a custom constant for e, use that one. Don't use any higher "accuracy", because it will make your variable overflow.
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
local real r = 123456789.0123456789
call BJDebugMsg(R2S(r))
endfunction
//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
set gg_trg_Untitled_Trigger_001 = CreateTrigger( )
call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions )
endfunction
precision is 8, not 7 characters
prints 123456784.000
private static method onInit takes nothing returns nothing
local real e1 = 2.7182818
local real e2 = 2.718282
call BJDebugMsg(R2S(e1*e1*e1*e1*e1*e1*e1*e1*e1*e1*e1))
call BJDebugMsg(R2S(e2*e2*e2*e2*e2*e2*e2*e2*e2*e2*e2))
endmethod
Why are you using R2S?... I can't take anything you say seriously when you aren't using R2SW, lol.
Float has log(2^(23 + 1)) = 7.22 significant bits. The plus one comes from the normalization of the mantissa, from which you can save one extra, the so-called "hidden" bit. However, you don't really have eight significant bits but something between seven and eight. So what does that mean? That means that you don't have enough space to store every number with eight significant bits, but only about 25% of them. However, this is implementation dependent and nobody can guarantee you that you (accidentaly) hit a number which gets stored like this, if this was even implemented at all.
static method div takes thistype c1, thistype c2 returns thistype
local thistype c3 = thistype.allocate()
local real dv = c2.re*c2.re + c2.im*c2.im
if (dv!=0) then
set c3.re = (c1.re*c2.re + c1.im*c2.im)/dv
set c3.im = (c1.im*c2.re - c1.re*c2.im)/dv
else
set c3.re = c1.re*c2.re + c1.im*c2.im
set c3.im = c1.im*c2.re - c1.re*c2.im
endif
return c3
endmethod
method operator arg takes nothing returns real
return Atan(this.im/this.re)
endmethod
static method sqrt takes thistype c returns thistype
local thistype c2 = thistype.allocate()
if c.im==0 then
set c2.re = SquareRoot(c.re)
set c2.im = 0
else
set c2.re = SquareRoot((c2.re + SquareRoot(c.re*c.re + c.im*c.im))/2)
set c2.im = SquareRoot((c2.re - SquareRoot(c.re*c.re + c.im*c.im))/2)
if c.im < 0 then
set c2.im = -c2.im
endif
endif
return c2
endmethod
set c2.re = SquareRoot((c.re + SquareRoot(c.re*c.re + c.im*c.im))/2)
set c2.im = SquareRoot((c.re - SquareRoot(c.re*c.re + c.im*c.im))/2)
method operator arg takes nothing returns real
if this.im>0 then
return pi/2 - Atan2(this.im, this.re)
else
return -pi/2 - Atan2(this.im, this.re)
endif
endmethod
Any complex number (=/= 0) has only 2 roots (and not 4...)
Did anyone say something different?
static method sqrt takes thistype c returns thistype
* ~ It returns sqrt(c)
* ~ It returns the SquareRoot I choose (because there is actually four squareRoots : two with negative
* imaginary parts and two with positive imaginary parts).
* Basically you'll never have any use of this I think it is more nerdy than anything.
Complex c1 = Complex.create()
Complex c2 = Complex.create()
c1.re = 1
c1.im = 1
c2.re = 2
c2.im = 2
c3 = Complex.add(c1, c2)
Complex c1 = Complex.create()
Complex c2 = Complex.create()
c1.re = 1
c1.im = 1
c2.re = 2
c2.im = 2
c3 = c1.add(c2)
c3*(c1 + c2)
and output it as string, I have to do this:local Complex c1 = Complex.create()
local Complex c2 = Complex.create()
local Complex c3 = Complex.create()
set c1.re = 1
set c1.im = -3
set c2.re = 1.5
set c2.im = -4
set c3.re = 2
set c3.im = 1
call BJDebugMsg(Complex.mul(c3, Complex.add(c1, c2)).toString())
local Complex c1 = Complex.create(1, -3)
local Complex c2 = Complex.create(1.5, -4)
local Complex c3 = Complex.create(2, 1)
call BJDebugMsg(c3.mul(c1.add(c2)).toString())
Okay updated.
static method create takes real r, real i return thistype
static method create takes real r, real i returns /* <- */ thistype
local Complex c = Complex.create(4, -1.5)
call BJDebugMsg(Complex.sqrt(c).toString()) // Output: 2.034 - 1.374i
I can't really fix my mind on static and non static.
Okay .add .sub .mul .div sounds good.
But what about .conj ? Static/Non static ? Returns or intern ?
I can't really think of a way to unify it nicely.
Complex.
for every operation increases verbosity.thistype
after doing the modification, because then you can concatenate actions:local Complex c1 = Complex.create(1, 2)
local Complex c2 = c1.add(c1).conj().sqrt()
local Complex c = Complex.create(4, -1.5)
local Complex c2 = Complex.create(2, 2)
set c = Complex.add(c, c2)
call BJDebugMsg(I2S(c))