[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#442568: glibc: floor() is giving incorrect results on alpha architecture



reassign 442568 linux-2.6
severity 442568 important
merge 411813 442568
thanks

On Sun, Sep 16, 2007 at 11:23:01AM -0400, Kamaraju Kusumanchi wrote:
> Package: glibc
> Severity: normal
> 
> Consider the following code
> 
> $cat double_comparison.c
> #include <assert.h>
> #include <float.h>
> #include <math.h>
> #include <stdio.h>
> 
> int main() {
>   double x;
> 
>   printf("%s%d\n", "DBL_MANT_DIG = ", DBL_MANT_DIG);
>   x = ldexp (1.0, DBL_MANT_DIG) - 1.0;
>   printf("%lf %lf\n", x, floor(x));
>   assert(x == floor(x));    /* does not seem to work in alpha */
>   return 0;
> }
> 
> On i386 machine
> $gcc -Wall double_comparison.c -lm
> 
> $./a.out
> DBL_MANT_DIG = 53
> 9007199254740991.000000 9007199254740991.000000
> 
> However the assertion fails on alpha architecture because the value is
> 9007199254740991.000000 and the floor gives 9007199254740990.000000
> 
> This behaviour makes guile-1.8 (version 1.8.2+1-2) FTBFS on alpha architecture.
> The corresponding build log can be found at
> http://buildd.debian.org/fetch.cgi?&pkg=guile-1.8&ver=1.8.2%2B1-2&arch=alpha&stamp=1188100514&file=log
> 
> >>From guile-1.8-1.8.2+1/test-suite/standalone/test-round.c the lines where the
> guile-1.8 build fails is 
> 
>       /* 2^DBL_MANT_DIG-1
>          In the past scm_c_round had incorrectly incremented this value, due
>          to the way that x+0.5 would round upwards (in the usual default
>          nearest-even mode on most systems).  */
>       x = ldexp (1.0, DBL_MANT_DIG) - 1.0;
>       assert (x == floor (x));      /* should be an integer already */
>       assert (scm_c_round (x) == x);  /* scm_c_round should return it unchanged */
> 
> Initially I asked about this problem on debian-devel. Steve Langasek mentioned
> that this is a bug in glibc. So I am filing it here. The discussion can be
> found at http://lists.debian.org/debian-devel/2007/09/msg00536.html
> 

This is not a glibc problem but a kernel problem that has already been
solved.

EV4 to EV56 CPU are not IEEE compliant, and does not round the results
correctly. This can be fixed by enabling MATHEMU in the kernel:

config MATHEMU 
 tristate "Kernel FP software completion" if DEBUG_KERNEL && !SMP 
 default y if !DEBUG_KERNEL || SMP 
 help 
 This option is required for IEEE compliant floating point arithmetic 
 on the Alpha. The only time you would ever not say Y is to say M in 
 order to debug the code. Say Y unless you know what you are doing. 

Please upgrade your kernel to a version which has this option enabled. 

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net




Reply to: