It is only a small issue that compile time calculations do follow not the same rules. Perhaps this difference should be mentioned clearly in the manual and the helpfile.
The only thing that bothers me is that one does not know when the optimizer is capable to step over from run time calculation to compile time calculation (which is what happened here: the "Wrd1" variable was never used, the literal value was used directly, see the conclusions in http://www.mikroe.com/forum/viewtopic.php?t=20170 and below).
2010-05-07: I changed my mind, the above reasoning that this is a harmless phenomenon is not valid. This is clearly a difference in result due to an optimisation activity of the compiler. Even if the variable "Wrd1" was not actually used, the outcome of the code should be the same as if it was. Optimisation activities should never influence the result. So, I still consider this a major issue (I did also change the title to reflect the actual issue).
valid for mP v1.50 - v4.10
======================
The problem of http://www.mikroe.com/forum/viewtopic.php?t=20170 is still valid:
Problem:
Hi Janni, I think there are still some differences somewhere, the code in http://www.mikroe.com/forum/viewtopic.php?t=20170 still gives 2 different results:Janni wrote:No more differences between calculations at compile time and runtime!.
Code: Select all
program Type_Casting_cont;
var Wrd1, Wrd2: word;
Percentage: byte;
procedure Proc(TotalMemSize: word);
var I: byte;
begin
// ------------ test ------------- //
Wrd1 := 3968;
Percentage := 60;
Wrd2 := Wrd1 * Percentage div 100; // Wrd2 = as expected (2380)
Wrd2 := TotalMemSize * Percentage div 100; // Wrd2 = faulty (414)
// ------------ end test ------------- //
end;
begin
Proc(3968);
end.
----------------------------------
Janni's answer:
No, it does not. The runtime calculation is correct. You just crossed the the word-type range (3968*100=396 800) as calculations follow from left to right and the highest type of involved operands is assumed. The compilation time calculations are wrong, though, because wrong types were used (type of operands is larger than word). Try thisDany wrote: I do not know if it has something to to with the left-side rule in expression evaluation.
Code:
Wrd2 := word(Wrd1 * Percentage) div 100;
and you'll get the 'right' result (i.e. reflecting the real operands' types).
You found a bug, but it's on the compile-time side. Apparently, operands are not exactly represented in compile-time calculations .
Please report it in the beta-testing forum, so it won't be overlooked.
-------------------
The only actual difference between the two cases is that one calculation used the local variable, and the other one a parameter, both of the same size (word).
In the first link http://www.mikroe.com/forum/viewtopic.php?t=20170 you can see that it is due to ram/code optimisations: the variable "Wrd1" is not used but its value is used directly for further calculation (which makes it a compile time calculation):
Code: Select all
// ------------ test ------------- //
Wrd1 := 3968; //<---- this variable was not used by the compiler, its value was used as a literal one
Percentage := 60;
Wrd2 := Wrd1 * Percentage div 100; // Wrd2 = as expected (2380) <--- compile time calculation
Wrd2 := TotalMemSize * Percentage div 100; // Wrd2 = faulty (414) <--- run time calculation
// ------------ end test ------------- //
Code: Select all
// ------------ test ------------- //
Percentage := 60;
Wrd2 := 3968 * Percentage div 100; // Wrd2 = as expected (2380) <--- compile time calculation
Wrd2 := TotalMemSize * Percentage div 100; // Wrd2 = faulty (414) <--- run time calculation
// ------------ end test ------------- //