rvjansen / simula67

0 stars 0 forks source link

FOR i:= n2 // 2 STEP n UNTIL imax DO prime(i) := FALSE * fails with 'FIXED POINT OVFL #2

Open rvjansen opened 5 months ago

rvjansen commented 5 months ago

Reported by Walter Müller:

Given the program:

COMMENT
* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
* 
*  Revision History:
* Date         Rev Version  Comment
* 2017-12-25   975   1.2    use sqrt(nmax) as outer loop end
* 2017-12-24   973   1.1    use WHILE not FOR to avoid compiler bug 
* 2017-12-23   972   1.0.1  change (n-1)/2 --> n/2
* 2017-09-17   951   1.0    Initial version
* 2017-09-08   949   0.1    First draft
*
* Note on SIMULA 67 (VERS 12.00) complier bug workaround
* - an inner loop codes as
*     FOR i:= n2 // 2 STEP n UNTIL imax DO prime(i) := FALSE
*   fails with 'FIXED POINT OVFL at line' of the FOR loop.
* - The equivalent WHILE loop used below works.
*;

BEGIN
   INTEGER nmax,prnt,imax,nmsqrt;
   INTEGER i,n,imin;
   INTEGER np,il,nl;
   BOOLEAN ARRAY prime(1:5000000);

   nmax := InInt;
   prnt := InInt;

   IF nmax < 10 OR nmax > 10000000 THEN BEGIN
      OutText("nmax out of range (10...10000000), abort");
      GOTO done;
   END;

   nmsqrt := Entier(Sqrt(nmax));
   imax := (nmax-1) // 2;
   FOR i := 1 STEP 1 UNTIL imax DO prime(i) := TRUE;

   FOR n := 3 STEP 2 UNTIL nmsqrt DO BEGIN
      IF prime(n//2) THEN BEGIN
         i := (n*n) // 2;
         WHILE i <= imax DO BEGIN
            prime(i) := FALSE;
            i:= i +  n;
         END;
      END;
   END;

   IF prnt > 0 THEN BEGIN
      OutText("List of Primes up to ");
      OutInt(nmax,8);
      OutImage;
      OutInt(2,8);
      np := 1;
      FOR i := 1 STEP 1 UNTIL imax DO BEGIN
         IF prime(i) THEN BEGIN
            OutInt(1+2*i,8);
            np := np + 1;
            IF np = 10 THEN BEGIN
               OutImage;
               np := 0;
            END;
         END;
      END;
      IF np > 0 THEN OutImage;
   END;

   il :=  4;
   nl := 10;
   np :=  1;

   FOR i := 1 STEP 1 UNTIL imax DO BEGIN
      IF prime(i) THEN np := np + 1;
      IF i = il THEN BEGIN
         nl := 2*il + 2;
         OutText("pi(");
         OutInt(nl,8);
         OutText(")=");
         OutInt(np,8);
         OutImage;
        il := 10*(il+1)-1;
      END;
   END;

   IF nl < nmax THEN BEGIN
      OutText("pi(");
      OutInt(nmax,8);
      OutText(")=");
      OutInt(np,8);
      OutImage;
   END;

   done:
   OutImage;
END;

Fails with:

ZYQ994   SIMULA 67 RUN TIME SYSTEM : VERSION 12.00, DATE OF RELEASE  9 AUG 1985
ZYQ994   SIMULA PROGRAM COMPILED ON 29 DEC 2017 AT 19:58:50.36, START OF EXECUTION ON 29 DEC 2017 AT 19:58:50.36
ZYQ994   PROCESSING OPTIONS : DUMP=1,HIARCHY=0,LINECNT=64,SIZE=5885952,TRACE=0,SYMBDUMP=1
ZYQ077****FIXED POINT OVFL at line 00037 *******************************************************************************************


ZYQ994   END OF SIMULA PROGRAM EXECUTION AT 19:58:52.56   EXECUTION TIME 1.57 SEC.   RETURN CODE IS #00000008
ZYQ994   00000 STORECOLLAPSES, DATA STORAGE USED : 5000568 BYTES
peter-sylvester commented 5 months ago

He problem doesn't seem to be in the FOR loop but most likely in the ININT system function.