Hi,
I came across a bug in the DCAL compiler when trying to hard-code a large real value: I was assigning a value of 189999.1 to a real variable, but the resulting value of the variable was -6608.9 !
I spent quite a lot of time trying to understand what was going on before I realised what was going on and the resulting a work-around for the problem. I thought I should share my experience (and the work-around) in the hope that I may save others the confusion and wasted time.
It appears that the DCAL compiler is treating the whole number part of a hard-coded real as an integer. As integers can only have values in the range -32768 to +32767, there is obviously going to be a problem if you hard-code a real number outside this range. What happens of course is that the value 'wraps around' within the allowable range of values (e.g. 32767+1 gives a result of -32768),
If I keep subtracting 64k from my hard-coded value of 189999.1 until I get a number within the allowable integer range then I end up with -6608.9 (189999.1 - 3*65536). So it is wrapping around like an integer as per my notes above.
The workaround is to avoid hard-coding individual real values outside the valid integer range. If you need to hard-code a real value outside this range then I have found 2 ways to do this:
1. Code a formula that results in your desired value, but only using values within the integer range in your formula (e.g. instead of hard coding 189999.1 you could code (32000.0 *5.0)+29999.1 or 31666.5166666667 * 6.0),
2. Hard=code the value as a string and convert it to a real value.
The following DCAL code demonstrates the above:
I came across a bug in the DCAL compiler when trying to hard-code a large real value: I was assigning a value of 189999.1 to a real variable, but the resulting value of the variable was -6608.9 !
I spent quite a lot of time trying to understand what was going on before I realised what was going on and the resulting a work-around for the problem. I thought I should share my experience (and the work-around) in the hope that I may save others the confusion and wasted time.
It appears that the DCAL compiler is treating the whole number part of a hard-coded real as an integer. As integers can only have values in the range -32768 to +32767, there is obviously going to be a problem if you hard-code a real number outside this range. What happens of course is that the value 'wraps around' within the allowable range of values (e.g. 32767+1 gives a result of -32768),
If I keep subtracting 64k from my hard-coded value of 189999.1 until I get a number within the allowable integer range then I end up with -6608.9 (189999.1 - 3*65536). So it is wrapping around like an integer as per my notes above.
The workaround is to avoid hard-coding individual real values outside the valid integer range. If you need to hard-code a real value outside this range then I have found 2 ways to do this:
1. Code a formula that results in your desired value, but only using values within the integer range in your formula (e.g. instead of hard coding 189999.1 you could code (32000.0 *5.0)+29999.1 or 31666.5166666667 * 6.0),
2. Hard=code the value as a string and convert it to a real value.
The following DCAL code demonstrates the above:
Code: Select all
PROGRAM RealTest;
VAR
r : real;
tempbln : boolean;
BEGIN
r := 189999.1;
getrl (r); ! has a value of -6608.9
tempbln := cvstrll ('189999.1', r);
getrl (r); ! has correct value of 189999.1
r := 31666.5166666667 * 6.0;
getrl (r); ! has correct value of 189999.1
r := (32000.0 *5.0)+29999.1;
getrl (r); ! has correct value of 189999.1
END RealTest.
David Henderson
dhSoftware - Add-on Macros for DataCAD
dhSoftware - Add-on Macros for DataCAD