Opened 6 years ago

Last modified 4 years ago

## #8285 new bug

# unexpected behavior with encodeFloat on large inputs

Reported by: | carter | Owned by: | |
---|---|---|---|

Priority: | normal | Milestone: | |

Component: | Compiler | Version: | 7.7 |

Keywords: | Cc: | ||

Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |

Type of failure: | Incorrect result at runtime | Test Case: | |

Blocked By: | Blocking: | ||

Related Tickets: | Differential Rev(s): | ||

Wiki Page: |

### Description (last modified by )

> 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

### Change History (8)

### comment:1 Changed 6 years ago by

### comment:2 follow-ups: 4 7 Changed 6 years ago by

Fwiw, `encodeFloat 1 (2^31)`

behaves just like the C99 function ldexp(3) does for those arguments.

PS: Now I see the problem,

Prelude> 2^31-1 :: Int 2147483647 Prelude> 2^31 :: Int -2147483648

### comment:4 Changed 5 years ago by

Replying to hvr:

PS: Now I see the problem

What is exactly the problem? That the second argument to `encodeFloat`

is treated as a 32 bit integer?

### comment:5 Changed 5 years ago by

Milestone: | 7.10.1 → 7.12.1 |
---|

Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

### comment:7 Changed 4 years ago by

Description: | modified (diff) |
---|

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

### comment:8 Changed 4 years ago by

Milestone: | 8.0.1 |
---|

**Note:**See TracTickets for help on using tickets.

This seems like its worth fixing, if theres a reasonable solution. My understanding is the the current code just punts on handling these corner cases properly