[comp.unix.cray] 4.0 beta on a Cray

jones@ut-emx.uucp (William L. Jones) (02/19/91)

Since perl uses floating point arithmetic 20.0/5.0 != 4.0 on a cray.
This breaks lib/bigint.pl so that lib/big.t fails under perl 4.0 beta and
probably any other version of perl.  There is a context  diff that follows 
that insures perl generates the correct answer for case like the above 
on a cray. perl 4.0 beta passes all of the regression test on the cray with
this patch. (I hope cray fixes there floating point divide on the next machine).

I have not found any other problems with perl 4.0 beta.  It installed
very cleanly under UNICOS 5.1.11.

Lary, would please incorporate this patch into perl 4.0.
I am sure that there will be other perl packages that will run
into this problem with floating point arithmetic on crays.

Bill Jones
----------------


*** eval.c	Sun Feb 17 23:08:57 1991
--- orig/eval.c	Sun Feb 17 22:38:56 1991
***************
*** 731,753 ****
      case O_DIVIDE:
      	if ((value = str_gnum(st[2])) == 0.0)
      	    fatal("Illegal division by zero");
- #ifdef cray
- 	/* insure that 20./5. == 4. */
- 	{
- 	     double x;
- 	     int    k;
- 	     x =  str_gnum(st[1]);
- 	     if ((double)(int)x     == x &&
- 	         (double)(int)value == value &&
- 	         (k = (int)x/(int)value)*(int)value == (int)x) {
- 		 value = k;
- 	     } else {
- 		 value = x/value;
- 	     }
-         }
- #else
  	value = str_gnum(st[1]) / value;
- #endif
  	goto donumset;
      case O_MODULO:
  	tmplong = (long) str_gnum(st[2]);
--- 731,737 ----
*** orig/consarg.c	Sun Feb 17 22:39:00 1991
--- consarg.c	Sun Feb 17 23:15:36 1991
***************
*** 349,355 ****
  	    if (value == 0.0)
  		yyerror("Illegal division by constant zero");
  	    else
! 		str_numset(str,str_gnum(s1) / value);
  	    break;
  	case O_MODULO:
  	    tmplong = (unsigned long)str_gnum(s2);
--- 349,372 ----
  	    if (value == 0.0)
  		yyerror("Illegal division by constant zero");
  	    else
! #ifdef cray
!             /* insure that 20./5. == 4. */
!             {
!             	double x;
!              	int    k;
!              	x =  str_gnum(s1);
!              	if ((double)(int)x     == x &&
!                     (double)(int)value == value &&
!                     (k = (int)x/(int)value)*(int)value == (int)x) {
!                     value = k;
!              	} else {
!                     value = x/value;
!              	}
! 	    	str_numset(str,value);
!             }
! #else
! 	    str_numset(str,str_gnum(s1) / value);
! #endif
  	    break;
  	case O_MODULO:
  	    tmplong = (unsigned long)str_gnum(s2);