From: Date: March 31 2008 10:46pm Subject: Re: bk commit into 5.0 tree (kaa:1.2597) BUG#15936 List-Archive: http://lists.mysql.com/commits/44710 Message-Id: <20080331204648.GA32153@janus.mylan> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Hi! ok to push On Mar 14, Alexey Kopytov wrote: > ChangeSet@stripped, 2008-03-14 13:25:37+03:00, kaa@kaamos.(none) +4 -0 > Fix for bug #15936: "round" differs on Windows to Unix > > Both of our own implementations of rint(3) were inconsistent with the > most common behavior of rint() on those platforms that have it: round > to nearest, break ties by rounding to nearest even. perhaps we need to call fesetround() in mysqld to set rounding mode to nearest even explicitly ? > Fixed by leaving just one implementation of rint() in our source tree, > and changing its behavior to match the most common native > implementations on other platforms. > > diff -Nrup a/include/my_global.h b/include/my_global.h > --- a/include/my_global.h 2007-11-30 03:37:04 +03:00 > +++ b/include/my_global.h 2008-03-14 13:25:36 +03:00 > @@ -483,9 +483,42 @@ typedef unsigned short ushort; > #define test_all_bits(a,b) (((a) & (b)) == (b)) > #define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1)) > #define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0]))) > + > #ifndef HAVE_RINT > -#define rint(A) floor((A)+(((A) < 0)? -0.5 : 0.5)) > -#endif > +/** > + All integers up to this number can be represented exactly as double precision > + values (DBL_MANT_DIG == 53 for IEEE 754 hardware). > +*/ > +#define MAX_EXACT_INTEGER ((1LL << DBL_MANT_DIG) - 1) > + > +/** > + rint(3) implementation for platforms that do not have it. > + Always rounds to the nearest integer with ties being rounded to the nearest > + even integer to mimic glibc's rint() behavior in the "round-to-nearest" > + FPU mode. Hardware-specific optimizations are possible (frndint on x86). > + Unlike this implementation, hardware will also honor the FPU rounding mode. > +*/ > + > +inline double rint(double x) use 'static inline' > +{ > + double f, i; > + f = modf(x, &i); assuming, modf() is more portable than rint()... > + > + /* > + All doubles with absolute values > MAX_EXACT_INTEGER are even anyway, > + no need to check it. > + */ > + if (x > 0.0) > + i += (double) ((f > 0.5) || (f == 0.5 && > + i <= (double) MAX_EXACT_INTEGER && > + (longlong)i % 2)); > + else > + i -= (double) ((f < -0.5) || (f == -0.5 && > + i >= (double) -MAX_EXACT_INTEGER && > + (longlong)i % 2)); > + return i; > +} > +#endif /* HAVE_RINT */ > Regards / Mit vielen Grüssen, Sergei -- __ ___ ___ ____ __ / |/ /_ __/ __/ __ \/ / Sergei Golubchik / /|_/ / // /\ \/ /_/ / /__ Principal Software Developer/Server Architect /_/ /_/\_, /___/\___\_\___/ MySQL GmbH, Dachauer Str. 37, D-80335 München <___/ Geschäftsführer: Kaj Arnö - HRB München 162140