Can someone explain this interesting phenomenon

 

I define x as a double, assign to x the value of 5 divided by 2, and then print x. See code below.

double x = 5 / 2;
Print ("five divided by two is ", x);

The result, as printed in the journal tab, is:

2012.05.06 18:12:28 2012.04.26 12:34 Range Breakout EA (alpha 2a) EURUSD,M15: five divided by two is 2

The result is obviously wrong because 5 divided by 2 is not 2 but instead is 2.5.

However, if I use the following code:

double x = 5.0 / 2.0;
Print ("five divided by two is ", x);

I get the correct result:

2012.05.06 18:27:50 2012.04.26 12:34 Range Breakout EA (alpha 2a) EURUSD,M15: five divided by two is 2.5

Can someone explain (and thereby help me to understand) why the first example does not produce the correct (expected) result. Could it be a weird typecasting rule, even though the book says that doubles have a higher priority (and therefore, 5 and 2 would be converted to doubles (5.0 and 2.0) before the division and the result (2.5) then stored in x)? Thanks.

 

It's not a weird typecasting rule at all.

In the first example you are making an integer division and the program expects that the result is an integer. Since you can store a integer into a double without loosing precision probably no compiler will throw a warning.

 
zzuegg:

It's not a weird typecasting rule at all.

In the first example you are making an integer division and the program expects that the result is an integer. Since you can store a integer into a double without loosing precision probably no compiler will throw a warning.


zzuegg:

I would agree with you if x was defined as an int. See Features of Integer Calculations in Operations and Expressions. However, if the expression on the right side of the assignment operation does not coincide with the type of the variable on the left side, the value of the expression to the right of the assignment operation is cast as the type of the variable to the left of the assignment operation sign. The documentation calls this "target-type cast". See Typecasting in Operations and Expressions. So, since x is defined as a double, the integer expression (5 / 2) on the right side of the assignment operation should have been re-cast as a double. The only thing I can think of (at least at the moment) is the division was performed as an integer expression (and therefore, under Features of Integer Calculations in Operations and Expressions, 5 divided by 2 would be 2, rather than 2.5) before the expression was re-cast as a double. But why do it that way? Wouldn't it be better to re-cast before performing the division?

 
Thirteen:


So, since x is defined as a double, the integer expression (5 / 2) on the right side of the assignment operation should have been re-cast as a double. The only thing I can think of (at least at the moment) is the division was performed as an integer expression (and therefore, under Features of Integer Calculations in Operations and Expressions, 5 divided by 2 would be 2, rather than 2.5) before the expression was re-cast as a double. But why do it that way? Wouldn't it be better to re-cast before performing the division?

The compiler takes it as it comes. It sees an integer divided by an integer and does that. Then it sees the result needs to be a double so it upcasts it to double. This is all very logical and very expected. There is no "look ahead" so that it "realizes" that eventually it will need to be a double so it upcasts straight away.
 
Thirteen:

I define x as a double, assign to x the value of 5 divided by 2, and then print x. See code below.

Read the Documentation . . . it even shows an example that covers your question.
 

You can force it casting to double or adding the floating point in the code.

double res  = (double) 5 / (double) 2;
double resb = 5.0 / 2.0; 
 
flaab:

You can force it casting to double ....

No you can't. MQL4 does not support Explicit Casting. Try it ...

int start(){
   // This EXPLICIT CAST does not work, although it compiles without error
   double test = ((double)2)/3;
   Comment("test="+test);
   
   return(0);
}

This script displays 0.000000

 

Thanks all for your explanations and citation to the documentation. Very helpful!

 
There is no explicit casting, but any of the following variations will work.
double Double(double d){ return(d); }
//   double test = ((double)2)/3;
   double test =     Double(2)/3;
   double test =   (     2+0.)/3;
   double test =             2/3.;
   double test =             2; test /= 3;
Reason: