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

http://www.dhsoftware.com.au

http://www.dhsoftware.com.au