From: SourceForge.net <noreply@so...>  20081209 21:58:18

Bugs item #2398360, was opened at 20081207 00:47 Message generated for change (Comment added) made by rumen You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=2398360&group_id=2435 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: gcc Group: None Status: Open Resolution: None Priority: 5 Private: No Submitted By: Roumen Petrov (rumen) Assigned to: Nobody/Anonymous (nobody) Summary: ldexp() functions mishandle exponent overflow Initial Comment: The mingwex library contain functions ldexpl() and ldexpf() . The function ldexp() from msvcrt library is buggy and as example result of ldexp(1., INT_MAX) is 0(zero) instead inf. The tested msvcrt is 7.0+. May be is fixed in recent but not system default libraries. As work around I test with a new mingwex double function. The body of ldexp() is same as for ldexpf() only float is replaced by double. After this the library is rebuild in crossenvironment. The test case is attached and results are: 1) before ldexpf(1., 2147483647)=0, errno=0 ldexp (1., 2147483647)=0, errno=0 ldexpl(1., 2147483647)=inf, errno=34 2) after ldexpf(1., 2147483647)=inf, errno=34 ldexp (1., 2147483647)=inf, errno=34 ldexpl(1., 2147483647)=inf, errno=34 The result for ldexp (double argument and result) is expected. The issue is for ldexpf (float argument and result). Before (mingwex library is from distribution) result is zero and without error. Is possible this to be compiler/linker issue, mainly in native build ?  >Comment By: Roumen Petrov (rumen) Date: 20081209 23:58 Message: Uhh, Keith you find the bug. I didn't realize that ldexpf use ldexp. All the time, may be because I expect this, I think that ldexpf call ldexpl (!). So may initial report is without base. This explain my initial subject/title/summary. About 6) The value of INT_MAX is from python function from math module. Now I see that implementation is not correct for overflow. For underflow it is not correct too. My test show that ldexpl(1., N) return nonzero and no error , if N is __LDBL_MIN_EXP__  64. For N=__LDBL_MIN_EXP__65 , the result is zero and errno is ERANGE. About ldexp_generic.c  looks good. No idea for replacement #define ldexp __mingw_ldexp. My experience show that results of math functions from msvcrt 7.0 are far from expected results from some test vectors. May be define has to be default if posix flag is set, i.e. same as for posix io. The python (www.python.org) provide a (may be too strict for some libraries) math regression test case. Test for ldexp is from <REPOROOT>/Lib/test/test_math.py .  Comment By: Keith Marshall (keithmarshall) Date: 20081209 18:57 Message: After some further thought, I believe we could adapt the existing MinGW implementation of ldexpl(), to provide a generic implementation for ldexpf() and ldexp(), such as the attached; (I already have a Makefile infrastructure patch to support such generic implementations). This would provide __mingw_ldexp(), __mingw_ldexpf() and __mingw_ldexpl() in libmingwex.a, with two of these aliased to ldexpf() and ldexpl() as appropriate, but leaving MSVCRT.DLL to provide ldexp(). This way, those who expect the MSVCRT behaviour would not be disappointed, while those who prefer the behaviour you advocate may #define ldexp __mingw_ldexp to get a (hopefully better) implementation. (Caveat: I haven't tested this rigorously). File Added: ldexp_generic.c  Comment By: Keith Marshall (keithmarshall) Date: 20081209 13:33 Message: Roumen, Thanks for the report; herewith, some initial comments: 1) Please choose a title, (SF call it the `summary'), which describes the actual problem. 2) C99 is extremely vague about how the ldexp() functions should handle exponent overflow; http://www.openstd.org/jtc1/sc22/wg14/www/docs/n1124.pdf 7.12.6.6 says only: The ldexp functions multiply a floatingpoint number by an integral power of 2. A range error may occur. 3) POSIX is more prescriptive; http://www.opengroup.org/onlinepubs/009695399/functions/ldexp.html says: Upon successful completion, these functions shall return x multiplied by 2, raised to the power exp.  If these functions would cause overflow, a range error shall occur and ldexp(), ldexpf(), and ldexpl() shall return ±HUGE_VAL, ±HUGE_VALF, and ±HUGE_VALL (according to the sign of x), respectively.  If the correct value would cause underflow, and is not representable, a range error may occur, and an implementation defined value shall be returned. In this latter case, the return value of 0.0 is preferred, especially if IEC 60559 floating point is supported. Additional requirements for IEC 60559 support also demand: If x is NaN, a NaN shall be returned. If x is ±0 or ±Inf, x shall be returned. If exp is 0, x shall be returned. If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall be returned. 4) libmingwex.a does not actually provide any implementation for either ldexp() or ldexpf(); the ldexpf() you see there is nothing more than a wrapper around the MSVCRT implementation of ldexp(). The bug you report lies in this Microsoft implementation. 5) MinGW's minimalist philosophy does not aim to fix Microsoft bugs; indeed there are even some users who get very upset, when we do so. While fixing this particular bug may be trivial, the fix doesn't belong in libmingwex.a, without a clear directive from a majority of the user community, to override the broken Microsoft behaviour. 6) Since the effect of any of the ldexp() functions is to add the value of the second argument to the exponent value already defined within the floating point representation of the first, it makes no sense whatsoever to add INT_MAX to a field value which is already bounded by the limits FLT_MIN_EXP...FLT_MAX_EXP, DBL_MIN_EXP...DBL_MAX_EXP or LDBL_MIN_EXP...LDBL_MAX_EXP. While it would be nice if all ldexp() implementations did trap this error, you should recognise that some don't, (Microsoft's being a case in point), and you should code defensively, to avoid the issue.  You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=2398360&group_id=2435 