Yup.    Does this diff fix it for you?

On 2/6/14, Daniel Dickman <didick...@gmail.com> wrote:
> I think I recently ran into a similar issue but I suspect the root cause
> might be the same. I think the floorl function is wrong for numbers slightly
> larger than -1 to numbers slightly below 0. In this range floorl returns -0
> instead of -1.
>
>> On Feb 5, 2014, at 3:57 AM, David Coppa <dco...@openbsd.org> wrote:
>>
>>
>> Hi!
>>
>> I hit this problem while working on updating math/R from version
>> 2.15.3 to the latest version (3.0.2).
>>
>> It started happening since upstream switched from double functions
>> to C99 long double functions (expl, fabsl, ...), during the R-3
>> development cycle.
>>
>> Take the following reduced test-case, adapted from what R's code
>> does:
>>
>> ---8<---
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <math.h>
>>
>> int main(void) {
>>    double theta = 1;
>>    long double lambda, pr, pr2;
>>
>>    lambda = (0.5*theta);
>>    pr = exp(-lambda);
>>    pr2 = expl(-lambda);
>>
>>    printf("theta == %g, pr == %Lg, pr2 == %Lg\n", theta, pr, pr2);
>>    exit(0);
>> }
>>
>> ---8<---
>>
>> This produces the following output on Linux (x86_64):
>>
>> theta == 1, pr == 0.606531, pr2 == 0.606531
>>
>> While on OpenBSD -current amd64:
>>
>> theta == 1, pr == 0.606531, pr2 == nan
>>
>> And indeed R-3's testsuite fails with the error message
>> "NaNs produced":
>>
>> Warning in pchisq(1e-300, df = 0, ncp = lam) : NaNs produced
>>> stopifnot(all.equal(p00, exp(-lam/2)),
>> +           all.equal(p.0, exp(-lam/2)))
>> Error: all.equal(p.0, exp(-lam/2)) is not TRUE
>> Execution halted
>>
>> Is this a bug in our expl() ?
>>
>> Ciao,
>> David
>>
>
Index: s_floorl.c
===================================================================
RCS file: /cvs/src/lib/libm/src/ld80/s_floorl.c,v
retrieving revision 1.2
diff -u -r1.2 s_floorl.c
--- s_floorl.c  25 Jul 2011 16:20:09 -0000      1.2
+++ s_floorl.c  7 Feb 2014 07:01:59 -0000
@@ -35,10 +35,12 @@
        jj0 = (se&0x7fff)-0x3fff;
        if(jj0<31) {
            if(jj0<0) { /* raise inexact if x != 0 */
-               if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
-                   if(sx==0) {se=0;i0=i1=0;}
-                   else if(((se&0x7fff)|i0|i1)!=0)
-                       { se=0xbfff;i0=i1=0;}
+               if(huge+x>0.0) {
+                   if(sx==0) {
+                        return 0.0L;
+                    } else if(((se&0x7fff)|i0|i1)!=0) {
+                       return -1.0L;
+                    }
                }
            } else {
                i = (0x7fffffff)>>jj0;

Reply via email to