MathFloor(), MathCeil() return wrong value

 

MathFloor(any value) return 0.

MathCeil (any value)  return 1.

MathRound() is right. 

 

What is any value?

Please show whole source code indicating described problem

 
stringo:

What is any value?

Please show whole source code indicating described problem

Sorry, I write a code to test these function, them return right value.
But when I give them a value which return from ChartGetInteger(), MathFloor() and MathCeil() return wrong value.
It's too strange.

void TestMath()
{
   long w, wmf, wmc, wmr;

   Print("Now direct assign value");
   w  = 717;
   wmf = MathFloor(w/2); //MathFloor return right
   wmc = MathCeil (w/2); //MathCeil  return right
   wmr = MathRound(w/2); //MathRound return right
   Print("w="+w+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);

   Print("Now get value from ChartGetInteger()");
   w  = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS,0); // It get the value right!
   wmf = MathFloor(w/2); //MathFloor return 0?
   wmc = MathCeil (w/2); //MathCeil  return 1?
   wmr = MathRound(w/2); //MathRound return right
   Print("w="+w+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);
}
Files:
testmath1.mq5  3 kb
 

It will print:

Now direct assign value
w=717, wmf=358, wmc=358, wmr=358
Now get value from ChartGetInteger()
w=717, wmf=0, wmc=1, wmr=358

ChartGetInteger() return a right value,
and MathRound() return a right value too,
but MathFloor() and MathCeil() return wrong value.

 

 

And if write

   Print("w="+w+", w/2="+w/2+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);
It will print:
Now direct assign value
w=717, w/2=358, wmf=358, wmc=358, wmr=358
Now get value from ChartGetInteger()
w=717, w/2=358, wmf=0, wmc=1, wmr=358

 

I find this problem when write a very simple sample of clock.
https://www.mql5.com/en/code/78
I just replace MathFloor() and MathCeil() with MathRound(), and I get right result.
So I think it is MathFloor() and MathCeil() problems.
But now it seems not.

LoongClock
  • votes: 11
  • 2010.02.05
  • Loong | English Russian Spanish Portuguese
  • www.mql5.com
A very simple sample of clock
 

Oh, I see.

This problems occur when passing a long integer as parameters of MathFloor() or MathCeil(). 

 

void TestMath()
{
   long w, wmf, wmc, wmr;
   long w1;
   double w2;
   Print("Now direct assign value");
   w  = 717;
   wmf = MathFloor(w/2); //MathFloor return right
   wmc = MathCeil (w/2); //MathCeil  return right
   wmr = MathRound(w/2); //MathRound return right
   Print("w="+w+", w/2="+w/2+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);

   Print("Now get value from ChartGetInteger()");
   w  = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS,0); // It get the value right!
   wmf = MathFloor(w/2); //MathFloor return 0?
   wmc = MathCeil (w/2); //MathCeil  return 1?
   wmr = MathRound(w/2); //MathRound return right
   Print("w="+w+", w/2="+w/2+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);

   Print("Now get value pass through a double variable");
   //w  = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS,0); // It get the value right!
   w2 = w/2;
   wmf = MathFloor(w2); //MathFloor return 0?
   wmc = MathCeil (w2); //MathCeil  return 1?
   wmr = MathRound(w2); //MathRound return right
   Print("w="+w+", w2="+w2+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);

   Print("Now get value pass through a long variable");
   //w  = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS,0); // It get the value right!
   w1 = w/2;
   wmf = MathFloor(w1); //MathFloor return 0?
   wmc = MathCeil (w1); //MathCeil  return 1?
   wmr = MathRound(w1); //MathRound return right
   Print("w="+w+", w1="+w1+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);
}

 It will print:

Now direct assign value
w=717, w/2=358, wmf=358, wmc=358, wmr=358
Now get value from ChartGetInteger()
w=717, w/2=358, wmf=0, wmc=1, wmr=358
Now get value pass through a double variable
w=717, w2=358.00000000, wmf=358, wmc=358, wmr=358
Now get value pass through a long variable
w=717, w1=358, wmf=0, wmc=1, wmr=358
 

 

But ChartGetInteger() must did something in this problem.
Because it will not occur any error, if you pass into MathFloor() a long variable which is not get from ChartGetInteger().

void TestMath2()
{
   long w, w1;
   long wmf, wmc, wmr;
   w=501;
   w1=w/2;
   wmf = MathFloor(w1); //MathFloor return 0?
   wmc = MathCeil (w1); //MathCeil  return 1?
   wmr = MathRound(w1); //MathRound return right
   Print("w="+w+", w1="+w1+", wmf="+wmf+", wmc="+wmc+", wmr="+wmr);
}
It will print:
w=501, w1=250, wmf=250, wmc=250, wmr=250
 
Loong:

But ChartGetInteger() must did something in this problem.
Because it will not occur any error, if you pass into MathFloor() a long variable which is not get from ChartGetInteger().

It will print:
w=501, w1=250, wmf=250, wmc=250, wmr=250


Loong,

study my example:


void OnStart()
  {
//---
   long a=7;
   double b=7;
   
   long long_wmf, long_wmc, long_wmr;
   double double_wmf, double_wmc, double_wmr;
   
   double_wmf = MathFloor((double)a/2); 
   double_wmc = MathCeil ((double)a/2);
   double_wmr = MathRound((double)a/2);
   
   long_wmf = (long)MathFloor((double)a/2); 
   long_wmc = (long)MathCeil ((double)a/2);
   long_wmr = (long)MathRound((double)a/2);
   
   
   Print(double_wmf, double_wmc, double_wmr);
   Print(long_wmf, long_wmc, long_wmr);
   
   double_wmf = MathFloor(b/2); 
   double_wmc = MathCeil (b/2);
   double_wmr = MathRound(b/2);
   
   long_wmf = (long)MathFloor(b/2); 
   long_wmc = (long)MathCeil (b/2);
   long_wmr = (long)MathRound(b/2);
   
   
   Print(double_wmf, double_wmc, double_wmr);
   Print(long_wmf, long_wmc, long_wmr);
   
  }



 
investeo:


Loong,

study my example:

Yeah, you are right. I should do typecasting.

But why the error only be occured when using return vlaue of ChartGetInteger()?

Please test this code: 

void TestMath4()
{
   long   lImmediate, lChartGetI;
   long   l_l_2;
   double d_l_2;
   double dmf, dmc, dmr;
   long   lmf, lmc, lmr;

   lImmediate = 717;
   lChartGetI = (long)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS,0); // It get the value right!
   Print("lImmediate="+lImmediate+", lChartGetI="+lChartGetI+", lChartGetI-lImmediate="+((double)lChartGetI-(double)lImmediate));
   d_l_2 = (double)lImmediate/2;
   l_l_2 = (long)((double)lImmediate/2);
   Print("                       d_l_2 or l_l_2    dmf           dmc           dmr           lmf  lmc  lmr");
   dmf = MathFloor(d_l_2);
   dmc = MathCeil (d_l_2);
   dmr = MathRound(d_l_2);
   lmf = (long)MathFloor(d_l_2);
   lmc = (long)MathCeil (d_l_2);
   lmr = (long)MathRound(d_l_2);
   Print("lImmediate >>        d_l_2="+d_l_2+", "+dmf+", "+dmc+", "+dmr+", "+lmf+", "+lmc+", "+lmr);
   dmf = MathFloor(l_l_2);
   dmc = MathCeil (l_l_2);
   dmr = MathRound(l_l_2);
   lmf = (long)MathFloor(l_l_2);
   lmc = (long)MathCeil (l_l_2);
   lmr = (long)MathRound(l_l_2);
   Print("lImmediate >>        l_l_2="+l_l_2+"         , "+dmf+", "+dmc+", "+dmr+", "+lmf+", "+lmc+", "+lmr);

   d_l_2 = (double)lChartGetI/2;
   l_l_2 = (long)((double)lChartGetI/2);
   dmf = MathFloor(d_l_2);
   dmc = MathCeil (d_l_2);
   dmr = MathRound(d_l_2);
   lmf = (long)MathFloor(d_l_2);
   lmc = (long)MathCeil (d_l_2);
   lmr = (long)MathRound(d_l_2);
   Print("lChartGetI >>        d_l_2="+d_l_2+", "+dmf+", "+dmc+", "+dmr+", "+lmf+", "+lmc+", "+lmr);
   dmf = MathFloor(l_l_2);
   dmc = MathCeil (l_l_2);
   dmr = MathRound(l_l_2);
   lmf = (long)MathFloor(l_l_2);
   lmc = (long)MathCeil (l_l_2);
   lmr = (long)MathRound(l_l_2);
   Print("lChartGetI >>        l_l_2="+l_l_2+"         ,   "+dmf+",   "+dmc+", "+dmr+",   "+lmf+",   "+lmc+", "+lmr);

   dmf = MathFloor((double)l_l_2);
   dmc = MathCeil ((double)l_l_2);
   dmr = MathRound((double)l_l_2);
   lmf = (long)MathFloor((double)l_l_2);
   lmc = (long)MathCeil ((double)l_l_2);
   lmr = (long)MathRound((double)l_l_2);
   Print("lChartGetI >>(double)l_l_2="+(double)l_l_2+", "+dmf+", "+dmc+", "+dmr+", "+lmf+", "+lmc+", "+lmr);
}

It will print:

lChartGetI >>(double)l_l_2=358.00000000, 358.00000000, 358.00000000, 358.00000000, 358, 358, 358
lChartGetI >>        l_l_2=358         ,   0.00000000,   1.00000000, 358.00000000,   0,   1, 358
lChartGetI >>        d_l_2=358.50000000, 358.00000000, 359.00000000, 358.00000000, 358, 359, 358
lImmediate >>        l_l_2=358         , 358.00000000, 358.00000000, 358.00000000, 358, 358, 358
lImmediate >>        d_l_2=358.50000000, 358.00000000, 359.00000000, 358.00000000, 358, 359, 358
                       d_l_2 or l_l_2    dmf           dmc           dmr           lmf  lmc  lmr
lImmediate=717, lChartGetI=717, lChartGetI-lImmediate=0.00000000

 

 

And why MathRound() can accept a int parameter then return right vlaue?

Reason: