summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@sun.com>2009-02-23 14:42:31 +0200
committerAlexey Kopytov <Alexey.Kopytov@sun.com>2009-02-23 14:42:31 +0200
commit2247fb7cd1cb5bb33a0476cd4b9b1106ebbf70c9 (patch)
tree8cbab18ef11dd6a2d9145bac3d88c64f57c3e062 /include
parentcdb052a5014e1a9609be3b099f1e2696287b6219 (diff)
parentcebaf077d2b46496a4a9111244b6412a7ca6b790 (diff)
downloadmariadb-git-2247fb7cd1cb5bb33a0476cd4b9b1106ebbf70c9.tar.gz
Manual merge to 5.1.
Diffstat (limited to 'include')
-rw-r--r--include/config-win.h9
-rw-r--r--include/my_global.h35
2 files changed, 33 insertions, 11 deletions
diff --git a/include/config-win.h b/include/config-win.h
index ab0926af864..3a21551ebbb 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -33,7 +33,6 @@ functions */
#include <sys/locking.h>
#include <winsock2.h>
-#include <math.h> /* Because of rint() */
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
@@ -223,13 +222,6 @@ typedef uint rf_SetTimer;
#define inline __inline
#endif /* __cplusplus */
-inline double rint(double nr)
-{
- double f = floor(nr);
- double c = ceil(nr);
- return (((c-nr) >= (nr-f)) ? f :c);
-}
-
#ifdef _WIN64
#define ulonglong2double(A) ((double) (ulonglong) (A))
#define my_off_t2double(A) ((double) (my_off_t) (A))
@@ -284,7 +276,6 @@ inline ulonglong double2ulonglong(double d)
#define HAVE_FLOAT_H
#define HAVE_LIMITS_H
#define HAVE_STDDEF_H
-#define HAVE_RINT /* defined in this file */
#define NO_FCNTL_NONBLOCK /* No FCNTL */
#define HAVE_ALLOCA
#define HAVE_STRPBRK
diff --git a/include/my_global.h b/include/my_global.h
index 8c25cbf802e..5250d24d0e1 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -578,8 +578,39 @@ typedef unsigned short ushort;
#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.
+*/
+
+static inline double rint(double x)
+{
+ double f, i;
+ f = modf(x, &i);
+ /*
+ 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 */
/* Define some general constants */
#ifndef TRUE