In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/e093953796c2b52df4a70fb9d48a4cad66bc6cc1?hp=8a00eddcbace6ea4d95ca7780e8ec310ce6feb88>

- Log -----------------------------------------------------------------
commit e093953796c2b52df4a70fb9d48a4cad66bc6cc1
Author: Jarkko Hietaniemi <[email protected]>
Date:   Wed Sep 3 20:36:53 2014 -0400

    POSIX math: if no fesetround, try fpsetround.
-----------------------------------------------------------------------

Summary of changes:
 ext/POSIX/POSIX.xs | 54 ++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs
index 62393eb..7cbd03a 100644
--- a/ext/POSIX/POSIX.xs
+++ b/ext/POSIX/POSIX.xs
@@ -122,6 +122,14 @@
 #  define FP_ZERO      4
 #endif
 
+/* We will have an emulation. */
+#ifndef FE_TONEAREST
+#  define FE_TONEAREST 0
+#  define FE_TOWARDZERO        1
+#  define FE_DOWNWARD  2
+#  define FE_UPWARD    3
+#endif
+
 /* C89 math.h:
 
    acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp
@@ -651,30 +659,44 @@ static int my_fegetround()
   return fegetround();
 #elif defined(FLT_ROUNDS)
   return FLT_ROUNDS;
-  /* XXX emulate using fpgetround() (HAS_FPGETROUND):
-   * FP_RN to nearest, FP_RM down, FP_RP, up, FP_RZ truncate */
+#elif defined(HAS_FPGETROUND)
+  switch (fpgetround()) {
+  default:
+  case FP_RN: return FE_TONEAREST;
+  case FP_RZ: return FE_TOWARDZERO;
+  case FP_RM: return FE_DOWNWARD;
+  case FE_RP: return FE_UPWARD;
+  }
 #else
   return -1;
 #endif
 }
 
+/* Toward minus infinity. */
+#define my_round_down(x) ((NV)((IV)(x >= 0.0 ? x : x - 0.5)))
+
+/* Toward plus infinity. */
+#define my_round_up(x) ((NV)((IV)(x >= 0.0 ? x + 0.5 : x)))
+
 static NV my_rint(NV x)
 {
 #ifdef FE_TONEAREST
   switch (my_fegetround()) {
   default:
-  case FE_TONEAREST:
-    return (NV)((IV)(x >= 0.0 ? x + 0.5 : x - 0.5)); /* like round() */
-  case FE_TOWARDZERO:
-    return (NV)((IV)(x)); /* like trunc() */
-  case FE_DOWNWARD:
-    return (NV)((IV)(x >= 0.0 ? x : x - 0.5));
-  case FE_UPWARD:
-    return (NV)((IV)(x >= 0.0 ? x + 0.5 : x));
+  case FE_TONEAREST:  return c99_round(x);
+  case FE_TOWARDZERO: return c99_trunc(x);
+  case FE_DOWNWARD:   return my_round_down(x);
+  case FE_UPWARD:     return my_round_up(x);
+  }
+#elif defined(HAS_FPGETROUND)
+  switch (fpgetround()) {
+  default:
+  case FP_RN: return c99_round(x);
+  case FP_RZ: return c99_trunc(x);
+  case FP_RM: return my_round_down(x);
+  case FE_RP: return my_round_up(x);
   }
 #else
-  /* XXX emulate using fpsetround() (HAS_FPGETROUND):
-   * FP_RN to nearest, FP_RM down, FP_RP, up, FP_RZ truncate */
   return NV_NAN;
 #endif
 }
@@ -2032,6 +2054,14 @@ fesetround(x)
     CODE:
 #ifdef HAS_FEGETROUND /* canary for fesetround */
        RETVAL = fesetround(x);
+#elif HAS_FPGETROUND /* canary for fpsetround */
+       switch (x) {
+        default:
+       case FE_TONEAREST:  RETVAL = fpsetround(FP_RN); break;
+       case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
+       case FE_DOWNWARD:   RETVAL = fpsetround(FP_RM); break;
+       case FE_UPWARD:     RETVAL = fpsetround(FP_RP); break;
+       }
 #else
        RETVAL = -1;
        not_here("fesetround");

--
Perl5 Master Repository

Reply via email to