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
}
]