Cube Root.

 

Hi.

The issue is as much simple as interesting. How to calculate the cube root of an inputed number.

We have MathPow(..., ...) only, and we can choose to get into the second parameter field a double value such as: double ATHIRD = 1 / THREE. Where THREE is a double value too (= 3.0).

Any evidences points out that the retuned ATHIRD figure is a four-digits one. So it invalidates the whole MathPow calculation for several inputs (-0,5525 for instance). If you try to calculare the cube root of that input by spreadsheet you will notice that (-0,5525)^(0.3333) is unvalid. And you will notice that by increasing the 3's the calculation becomes valid.

Is there any chance to make the calculator consider the ATHIRD as a floating number with more than 15 digits? Have I to call a special library?

Thanks,

Simon

 

Huh? I just don't believe it.

Can you make a minimal example program that proves that mql4 is not using full Double precision for floating point calculations?

 
7bit:

Huh? I just don't believe it.

Can you make a minimal example program that proves that mql4 is not using full Double precision for floating point calculations?

Try to set as follow:

double THREE = 3.0;

double ATHIRD = 1 / THREE;

double INPUT = -0,5525;

double CUBEROOT;

CUBEROOT = MathPow(INPUT,ATHIRD);

A script is enough. Unvalid is returned. While a common calculator returns -0.82056. AND THIS IS FOR EVERY NEGATIVE INPUTS ONLY.

 

You should have warned me that it will crash MT4 :-(

 

If it is ok with positive but fails with negative you might try the following:

1 - your INPUT is (SOME_NUMBER*SOME_NUMBER*SOME_NUMBER) or SOME_NUMBER^3

2 - for odd multiplication if SOME_NUMBER < 0, then INPUT < 0 too

3 - so, find MathPow( MathAbs(INPUT), ROOT_POW ), if your ROOT_POW is odd, place "-" in front of result.

Thats it.

 
hasayama:

If it is ok with positive but fails with negative you might try the following:

1 - your INPUT is (SOME_NUMBER*SOME_NUMBER*SOME_NUMBER) or SOME_NUMBER^3

2 - for odd multiplication if SOME_NUMBER < 0, then INPUT < 0 too

3 - so, find MathPow( MathAbs(INPUT), ROOT_POW ), if your ROOT_POW is odd, place "-" in front of result.

Thats it.

Realized, sounds smart. Thanks! Even if now we know that the best precision is very far to from being guaranted.

 

I think it is failing when it does the logarithm of the negative number


most likely it will calculate


MathPow(base, exponent)

as

MathExp(exponent * MathLog(base))


and does some special cases for exponent being integer numbers.


MathPow(-2, 3) will work but not MathPow(-2, 3.001)


none of them could be calculated as MathExp(exponent * MathLog(base)) but it recognizes the exponent 3 as a special case and calculates it differently. And it seems it fails in recognizing 1/3 as a special case for doing the cube root and I don't think it is because the lack of precision, they would have noticed during testing, they simply forgot to implement it.


It seems you must implement your own cuberoot function that explicitely does an if/else and treats negative numbers separately:

double MathCbrt(double x){
   if (x < 0){
      return(-MathPow(-x, 1.0/3.0));
   }else{
      return(MathPow(x, 1.0/3.0));
   }
}
Reason: