summaryrefslogtreecommitdiff
path: root/math/R/patches/patch-src_main_format.c
diff options
context:
space:
mode:
Diffstat (limited to 'math/R/patches/patch-src_main_format.c')
-rw-r--r--math/R/patches/patch-src_main_format.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/math/R/patches/patch-src_main_format.c b/math/R/patches/patch-src_main_format.c
new file mode 100644
index 00000000000..a369cbc6794
--- /dev/null
+++ b/math/R/patches/patch-src_main_format.c
@@ -0,0 +1,71 @@
+$NetBSD: patch-src_main_format.c,v 1.1 2011/11/20 04:57:03 markd Exp $
+
+NetBSD does not have rintl() or floorl() so use the OpenBSD implementation
+of rintl() in that case.
+
+--- src/main/format.c.orig 2011-10-02 22:02:34.000000000 +0000
++++ src/main/format.c
+@@ -130,6 +130,7 @@ void formatInteger(int *x, int n, int *f
+ # define R_nearbyintl rintl
+ # else
+ # define R_nearbyintl private_nearbyintl
++# ifndef __NetBSD__
+ long double private_nearbyintl(long double x)
+ {
+ long double x1;
+@@ -142,6 +143,55 @@ long double private_nearbyintl(long doub
+ if (x/2.0 == floorl(x/2.0)) return(x); else return(x1);
+ }
+ }
++# else
++#include <machine/ieee.h>
++
++#if LDBL_MAX_EXP != 0x4000
++/* We also require the usual bias, min exp and expsign packing. */
++#error "Unsupported long double format"
++#endif
++
++#define BIAS (LDBL_MAX_EXP - 1)
++
++static const float
++shift[2] = {
++#if LDBL_MANT_DIG == 64
++ 0x1.0p63, -0x1.0p63
++#elif LDBL_MANT_DIG == 113
++ 0x1.0p112, -0x1.0p112
++#else
++#error "Unsupported long double format"
++#endif
++};
++static const float zero[2] = { 0.0, -0.0 };
++
++long double private_nearbyintl(long double x)
++{
++ union {
++ long double e;
++ struct ieee_ext bits;
++ } u;
++ uint32_t expsign;
++ int ex, sign;
++ u.e = x;
++ expsign = (u.bits.ext_sign << 15) | u.bits.ext_exp;
++ ex = expsign & 0x7fff;
++
++ if (ex >= BIAS + LDBL_MANT_DIG - 1) {
++ if (ex == BIAS + LDBL_MAX_EXP)
++ return (x + x); /* Inf, NaN, or unsupported format */
++ return (x); /* finite and already an integer */
++ }
++ sign = expsign >> 15;
++ x += shift[sign];
++ x -= shift[sign];
++
++ if (ex < BIAS && x == 0.0L)
++ return (zero[sign]);
++
++ return (x);
++}
++# endif
+ # endif
+ # else /* no long double */
+ # ifdef HAVE_NEARBYINT