Manuel Chakravarty writes:
> 
> I found a bug in derived instances for Show that contain
> `Float' numbers.  Running
> 
>   data MassPnt  = MassPnt Float (Float, Float)
>                 deriving (Show)
> 
>   main = do
>          print 1.18088e+11
>          let p = MassPnt 1.18088e+11 (-0.768153, -0.742202)
>          print p
> 
> the first `print' is successfully executed, but the attempt
> to output `1.18088e+11' below the constructor `MassPnt'
> fails with
> 
>   Fail: Char.intToDigit: not a digit
> 

Hi,

thanks for a fine report ( `main=print (1.18088e+11 :: Float)' is the
shortest example that shows this one up.)

The bug is due to wonky tests for exceptional IEEE float values,
something that wasn't caught by our regression tests. 

The attached patch should apply to ghc-2.02/2.03 sources or later.

--Sigbjorn

*** ghc/lib/cbits/floatExtreme.lc.~1~   1997/05/18 04:26:47
--- ghc/lib/cbits/floatExtreme.lc       1998/01/29 13:39:58
***************
*** 7,10 ****
--- 7,15 ----
  source.
  
+ ToDo:
+   - avoid hard-wiring the fact that on an
+     Alpha we repr. a StgFloat as a double.
+     (introduce int equivalent of {ASSIGN,PK}_FLT? )
+ 
  \begin{code}
  
***************
*** 81,96 ****
  }
  
  StgInt
  isFloatNaN(f) 
  StgFloat f;
  {
!     int ix;
      int r;
  
!     ix = (int)f;
!     ix &= 0x7fffffff;
!     ix = 0x7f800000 - ix;
!     r = (int)(((unsigned int)(ix))>>31);
      return (r);
  }
  
--- 86,108 ----
  }
  
+ /* Same tests, this time for StgFloats. */
+ 
  StgInt
  isFloatNaN(f) 
  StgFloat f;
  {
! #if !defined(alpha_TARGET_OS)
!     /* StgFloat = double on alphas */
!     return (isDoubleNaN(f));
! #else
!     union { StgFloat f; int i; } u;
      int r;
+     u.f = f;
  
!     u.i &= 0x7fffffff;
!     u.i = 0x7f800000 - u.i;
!     r = (int)(((unsigned int)(u.i))>>31);
      return (r);
+ #endif
  }
  
***************
*** 99,108 ****
  StgFloat f;
  {
      int ix;
  
!     ix = (int)f;
!     ix &= 0x7fffffff;
!     ix ^= 0x7f800000;
!     return (ix == 0);
  }
  
--- 111,126 ----
  StgFloat f;
  {
+ #if !defined(alpha_TARGET_OS)
+     /* StgFloat = double on alphas */
+     return (isDoubleInfinite(f));
+ #else
      int ix;
+     union { StgFloat f; int i; } u;
+     u.f = f;
  
!     u.i &= 0x7fffffff;
!     u.i ^= 0x7f800000;
!     return (u.i == 0);
! #endif
  }
  
***************
*** 111,119 ****
  StgFloat f;
  {
!     int high, iexp;
  
!     high = (int)f;
!     iexp = high & (0xff << 23);
      return (iexp == 0);
  }
  
--- 129,143 ----
  StgFloat f;
  {
! #if !defined(alpha_TARGET_OS)
!     /* StgFloat = double on alphas */
!     return (isDoubleDenormalized(f));
! #else
!     int iexp;
!     union { StgFloat f; int i; } u;
!     u.f = f;
  
!     iexp = u.i & (0xff << 23);
      return (iexp == 0);
+ #endif
  }
  
***************
*** 122,127 ****
  StgFloat f;
  {
!     int high = (int)f;
!     return (high == 0x80000000);
  }
  
--- 146,158 ----
  StgFloat f;
  {
! #if !defined(alpha_TARGET_OS)
!     /* StgFloat = double on alphas */
!     return (isDoubleNegativeZero(f));
! #else
!     union { StgFloat f; int i; } u;
!     u.f = f;
! 
!     return (u.i  == (int)0x80000000);
! #endif
  }
]

Reply via email to