[GHC] #8285: unexpected behavior with encodeFloat on large inputs
GHC
ghc-devs at haskell.org
Sat Jan 23 23:13:02 UTC 2016
#8285: unexpected behavior with encodeFloat on large inputs
-------------------------------------+-------------------------------------
Reporter: carter | Owner:
Type: bug | Status: new
Priority: normal | Milestone: 8.0.1
Component: Compiler | Version: 7.7
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Incorrect result | Unknown/Multiple
at runtime | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
@@ -1,1 +1,3 @@
- benjamin scarlet discovered some unexpected behavior in encodeFloat today
+ {{{
+ > encodeFloat 1 1023
+ 8.98846567431158e307 -- ok
@@ -3,3 +5,2 @@
- {{{
- <bscarlet> > map (\x -> encodeFloat 1 (shiftL 1 x)) [30,31]
- [23:47:47] <lambdabot> [Infinity,0.0]
+ > encodeFloat 1 1024
+ Infinity -- ok
@@ -7,2 +8,2 @@
- [23:49:09] <arkeet> > encodeFloat 1 60
- [23:49:10] <lambdabot> 1.152921504606847e18
+ > encodeFloat 1 (2^31 - 1)
+ Infinity -- ok
@@ -10,16 +11,2 @@
- [23:49:09] <arkeet> > encodeFloat 1 60
- [23:49:10] <lambdabot> 1.152921504606847e18
- [23:49:18] <arkeet> er.
- [23:50:21] <bscarlet> down in the sane range I suspect it's just fine.
- [23:50:43] <bscarlet> > encodeFloat 1 1000
- [23:50:44] <lambdabot> 1.0715086071862673e301
- [23:50:52] <bscarlet> > encodeFloat 1 10000
- [23:50:53] <lambdabot> Infinity
- [23:50:58] <bscarlet> That's sane.
- [23:51:03] <arkeet> > encodeFloat 1 (2^31)
- [23:51:04] <lambdabot> 0.0
- [23:51:13] <bscarlet> That's what I think is weird.
- [23:51:19] <carter> bscarlet floats are weird
- [23:51:23] <arkeet> > encodeFloat 1 (2^31-1)
- [23:51:24] <lambdabot> Infinity
-
+ > encodeFloat 1 (2^31)
+ 0.0 -- not ok
@@ -27,6 +14,0 @@
- Benjamin did a wee bit of investigation, and the
- problem seems to lie in https://github.com/ghc/packages-integer-
- gmp/blob/master/cbits/float.c#L177
- in integer-gmp, where it deliberately doesn't handle the edge cases
- (probably worth investigating) if integer-simple has similar behavior or
- not
New description:
{{{
> encodeFloat 1 1023
8.98846567431158e307 -- ok
> encodeFloat 1 1024
Infinity -- ok
> encodeFloat 1 (2^31 - 1)
Infinity -- ok
> encodeFloat 1 (2^31)
0.0 -- not ok
}}}
--
Comment (by thomie):
I think this just needs an update to the `encodeFloat` docstring.
To confirms what hvr said in comment:2:
test.c:
{{{
#include <math.h>
#include <stdio.h>
#include <errno.h>
#include <fenv.h>
#include <limits.h>
#include <float.h>
void test(double x, int exp) {
errno = 0;
feclearexcept(FE_ALL_EXCEPT);
printf("(%f)*2^(%d) = %f\n", x, exp, ldexp(x, exp));
printf("errno: %d (ERANGE = %d), UNDERFLOW: %d, OVERFLOW: %d\n",
errno, ERANGE,
fetestexcept(FE_UNDERFLOW) == FE_UNDERFLOW,
fetestexcept(FE_OVERFLOW) == FE_OVERFLOW);
}
void main() {
// If the result overflows, a range error occurs, and the functions
// return HUGE_VAL, HUGE_VALF, or HUGE_VALL, respectively, with a sign
// the same as x.
test(1, 1024);
test(1, INT_MAX); // 2^31 - 1
printf("\n");
// If the result underflows, a range error occurs, and zero is
// returned.
test(1, DBL_MIN_EXP); // Not sure why not getting range error here,
test(1, -1074); // or here.
test(1, -1075); // but only starting here.
test(1, 1 << 31);
printf("\n");
// If x is positive infinity (negative infinity), positive infinity
// (negative infinity) is returned.
test(HUGE_VAL, 1 << 31);
test(- HUGE_VAL, 1 << 31);
}
}}}
{{{
$ gcc test.c -lm
$ ./a.out
(1.000000)*2^(1024) = inf
errno: 34 (ERANGE = 34), UNDERFLOW: 0, OVERFLOW: 1
(1.000000)*2^(2147483647) = inf
errno: 34 (ERANGE = 34), UNDERFLOW: 0, OVERFLOW: 1
(1.000000)*2^(-1021) = 0.000000
errno: 0 (ERANGE = 34), UNDERFLOW: 0, OVERFLOW: 0
(1.000000)*2^(-1074) = 0.000000
errno: 0 (ERANGE = 34), UNDERFLOW: 0, OVERFLOW: 0
(1.000000)*2^(-1075) = 0.000000
errno: 34 (ERANGE = 34), UNDERFLOW: 1, OVERFLOW: 0
(1.000000)*2^(-2147483648) = 0.000000
errno: 34 (ERANGE = 34), UNDERFLOW: 1, OVERFLOW: 0
(inf)*2^(-2147483648) = inf
errno: 0 (ERANGE = 34), UNDERFLOW: 0, OVERFLOW: 0
(-inf)*2^(-2147483648) = -inf
errno: 0 (ERANGE = 34), UNDERFLOW: 0, OVERFLOW: 0
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8285#comment:7>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list