delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2013/11/07/18:11:14

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
Message-ID: <527C1E6A.9020100@gmx.de>
Date: Fri, 08 Nov 2013 00:12:42 +0100
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121025 Thunderbird/16.0.2
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: rintl implementation.
X-Provags-ID: V03:K0:9kJSC4Zp5x8gWz2wSXqZ6ThWivsxDXfe3qcGbJJZCUEgrMvIyEi
m/zDoq+RDAMEvr4JK3p3jnLNwMCaWFARZos6dVk5x69/dFq6t3kLYg2wAmJKLeo6qEf/KJd
IpDOXEHdMzCTDxWUXtCC66yo5R7yt8t/OwlQnT3iw2dgOBHQrDyNoY/5bUkkxsptNE7KtXL
xOraxAjwEqclOcFh3tNLA==
Reply-To: djgpp-workers AT delorie DOT com

I have observed that the math library provides rintf and rint functions but the
one for long double argument (aka rintl) is still missing.  The patch provides it
together with a small test case.

Regards,
Juan M. Guerrero



2013-11-03  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


     * djgpp/include/libm/math.h: Added rintl declaration.

     * djgpp/include/math.h: Added rintl declaration.

     * djgpp/src/libm/math/makefile: Added rintl to goal list.

     * djgpp/src/libm/math/rintl.c: Implementation of rintl function.

     * djgpp/src/libm/math/w_remainder.c: Documentation for rintl added.

     * djgpp/src/docs/kb/wc204.txi: Info about rintl added.

     * djgpp/tests/cygnus/makefile:  Added rintl-t to goal list.

     * djgpp/tests/cygnus/rintl-t.c: Checks for rintl function.






diff -aprNU5 djgpp.orig/include/libm/math.h djgpp/include/libm/math.h
--- djgpp.orig/include/libm/math.h    2013-10-25 20:51:02 +0100
+++ djgpp/include/libm/math.h    2013-11-07 00:38:14 +0100
@@ -218,10 +218,12 @@ extern double scalb __P((double, double)

  #ifndef __cplusplus
  extern int matherr __P((struct exception *));
  #endif

+extern long double rintl __P((long double));
+
  /*
   * IEEE Test Vector
   */
  extern double significand __P((double));

diff -aprNU5 djgpp.orig/include/math.h djgpp/include/math.h
--- djgpp.orig/include/math.h    2013-10-25 20:51:04 +0100
+++ djgpp/include/math.h    2013-11-07 00:38:14 +0100
@@ -186,10 +186,11 @@ extern double logb(double);
  extern double nextafter(double, double);
  extern double remainder(double, double);
  extern double copysign(double, double);
  extern int ilogb(double);
  extern double rint(double);
+extern long double rintl(long double);
  extern double scalbn(double, int);
  extern double trunc(double);
  extern long double truncl(long double);
  extern long int lrint(double);
  extern long int lrintl(long double);
diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi    2013-10-25 20:51:06 +0100
+++ djgpp/src/docs/kb/wc204.txi    2013-11-07 00:38:14 +0100
@@ -1338,5 +1338,9 @@ to comply with the @acronym{C99} standar
  @findex llround AT r{ added}
  @findex llroundl AT r{ added}
  The @acronym{C99} functions @code{lroundf}, @code{lround}, @code{lroundl}, @code{llroundf},
  @code{llround} and @code{llroundl} were added to comply with the @acronym{C99} standard.
  These functions are available in two versions.
+
+@cindex @acronym{C99} compliance, @code{math.h}
+@findex rintl AT r{ added}
+The @acronym{C99} function @code{rintl} has been added to comply with the @acronym{C99} standard.
diff -aprNU5 djgpp.orig/src/libc/posix/string/makefile djgpp/src/libc/posix/string/makefile
--- djgpp.orig/src/libc/posix/string/makefile    2005-01-07 17:07:16 +0100
+++ djgpp/src/libc/posix/string/makefile    2013-11-07 00:38:14 +0100
@@ -1,7 +1,10 @@
+# Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details
  # Copyright (C) 2005 DJ Delorie, see COPYING.DJ for details
  TOP=../..

  SRC += strtok_r.c
  SRC += strerr_r.c
+SRC += strndup.c
+SRC += strnlen.c

  include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/src/libm/math/makefile djgpp/src/libm/math/makefile
--- djgpp.orig/src/libm/math/makefile    2013-10-25 20:51:28 +0100
+++ djgpp/src/libm/math/makefile    2013-11-07 00:38:14 +0100
@@ -180,10 +180,11 @@ SRC += lround.c
  SRC += lroundf.c
  SRC += lroundl.c
  SRC += llround.c
  SRC += llroundf.c
  SRC += llroundl.c
+SRC += rintl.c

  chobj = w_acos.def w_acosh.def w_asin.def s_asinh.def \
      s_atan.def w_atan2.def w_atanh.def w_j0.def \
      s_copysign.def w_cosh.def s_erf.def w_exp.def \
      s_fabs.def s_floor.def w_fmod.def s_frexp.def \
diff -aprNU5 djgpp.orig/src/libm/math/rintl.c djgpp/src/libm/math/rintl.c
--- djgpp.orig/src/libm/math/rintl.c    1970-01-01 01:00:00 +0100
+++ djgpp/src/libm/math/rintl.c    2013-11-07 23:36:22 +0100
@@ -0,0 +1,119 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+#include <stdint.h>
+#include <math.h>
+#include <libc/ieee.h>
+
+#if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+# define __gnuc_extension__  __extension__
+#else
+# define __gnuc_extension__
+#endif
+
+#define LONG_DOUBLE_BIAS (0x3FFFU)
+#define MAX_BIN_EXPONENT (16383)
+#define MIN_BIN_EXPONENT (-16382)
+#define BIN_DIGITS_IN_FRACTION (63)  /*  Amount of binary digits in fraction part of mantissa.  */
+#define BIN_DIGITS_IN_MANTISSAH (31)  /*  Amount of binary digits in msw of the fraction part of mantissa.  */
+#define ALL_DIGITS_ARE_SIGNIFICANT(exp) ((exp) > (BIN_DIGITS_IN_FRACTION - 1))
+#define NO_SIGNIFICANT_DIGITS_IN_MANTISSAL(exp) ((exp) < BIN_DIGITS_IN_MANTISSAH)
+#define MAGNITUDE_IS_LESS_THAN_ONE(exp) ((exp) < 0)
+#define IS_INF_OR_NAN(exp) ((exp) > MAX_BIN_EXPONENT)
+#define IS_ZERO(num) (((num).ldt.mantissah | (num).ldt.mantissal | (num).ldt.exponent) == 0)
+
+#define MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(pattern, exp) ((pattern) >> (exp))
+#define IS_MANTISSAH_INTEGRAL(num, unbiased_exponent) ((((num).ldt.mantissah & MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(0x7FFFFFFFUL, unbiased_exponent)) | (num).ldt.mantissal) == 0)
+#define ROUND_MANTISSAH_TO_INTEGER(num, unbiased_exponent) \
+(__gnuc_extension__ \
+ ({ \
+     const uint32_t rounded_mantissah = (uint32_t)(MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(0x7FFFFFFFUL, (unbiased_exponent)) >> 1);                     \
+ \
+     if ((rounded_mantissah & (num).ldt.mantissah) | (num).ldt.mantissal) \
+ { \
+       if ((unbiased_exponent) == (BIN_DIGITS_IN_MANTISSAH - 1)) \
+         (num).ldt.mantissal = 0x40000000UL; \
+ else \
+         (num).ldt.mantissah = (~rounded_mantissah & (num).ldt.mantissah) | MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(0x20000000UL, (unbiased_exponent));  \
+ } \
+ \
+     (num).ld += two63[(num).ldt.sign]; \
+     (num).ld -= two63[(num).ldt.sign]; \
+ }) \
+)
+
+#define SIGNIFICANT_FRACTION_DIGITS_MASK(pattern, exp) ((pattern) >> ((exp) - BIN_DIGITS_IN_MANTISSAH))
+#define IS_INTEGRAL(num, unbiased_exponent) (((num).ldt.mantissal & SIGNIFICANT_FRACTION_DIGITS_MASK(0x7FFFFFFFUL, (unbiased_exponent))) == 0)
+#define ROUND_MANTISSA_TO_INTEGER(num, unbiased_exponent) \
+(__gnuc_extension__ \
+ ({ \
+     const uint32_t rounded_mantissal = (uint32_t)(SIGNIFICANT_FRACTION_DIGITS_MASK(0x7FFFFFFFUL, (unbiased_exponent)) >> 1);                   \
+ \
+     if (rounded_mantissal & (num).ldt.mantissal) \
+       (num).ldt.mantissal = (~rounded_mantissal & (num).ldt.mantissal) | SIGNIFICANT_FRACTION_DIGITS_MASK(0x40000000UL, (unbiased_exponent));  \
+ \
+     (num).ld += two63[(num).ldt.sign]; \
+     (num).ld -= two63[(num).ldt.sign]; \
+ }) \
+)
+
+
+/* Adding a long double, x, to 2^63 will cause the result to be rounded based on
+   the fractional part of x, according to the implementation's current rounding
+   mode.  2^63 is the smallest long double that can be represented using all 63
+   significant digits. */
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+two63[2] = {
+  9.223372036854775808E+18,  /* 0, 0x3FFFE + 0x003F, 0x80000000U, 0x00000000U */
+ -9.223372036854775808E+18   /* 1, 0x3FFFE + 0x003F, 0x80000000U, 0x00000000U */
+};
+
+#ifdef __STDC__
+long double
+rintl(long double x)
+#else
+long double
+rintl(x)
+long double x;
+#endif
+{
+  volatile _longdouble_union_t ieee_value;
+  int unbiased_exponent;
+
+
+  ieee_value.ld = x;
+  unbiased_exponent = ieee_value.ldt.exponent - LONG_DOUBLE_BIAS;
+
+  if (ALL_DIGITS_ARE_SIGNIFICANT(unbiased_exponent))        /* Trigger an exception if INF or NAN  */
+    return IS_INF_OR_NAN(unbiased_exponent) ? x + x : x;    /* else return the number.  */
+  else
+  {
+    if (NO_SIGNIFICANT_DIGITS_IN_MANTISSAL(unbiased_exponent))
+    {
+      /* All significant digits are in msw. */
+      if (MAGNITUDE_IS_LESS_THAN_ONE(unbiased_exponent))
+      {
+        if (!IS_ZERO(ieee_value))
+        {
+          const int sign = ieee_value.ldt.sign;
+          int32_t mantissal = (int32_t)ieee_value.ldt.mantissah | (int32_t)ieee_value.ldt.mantissal;
+
+          ieee_value.ldt.mantissah &= 0xE0000000UL;
+          ieee_value.ldt.mantissah |= (mantissal | -mantissal) & 0x80000000UL;
+          ieee_value.ld += two63[ieee_value.ldt.sign]; \
+          ieee_value.ld -= two63[ieee_value.ldt.sign]; \
+          ieee_value.ldt.sign = sign;
+        }
+      }
+      else if (!IS_MANTISSAH_INTEGRAL(ieee_value, unbiased_exponent))
+        ROUND_MANTISSAH_TO_INTEGER(ieee_value, unbiased_exponent);
+    }
+    else if (!IS_INTEGRAL(ieee_value, unbiased_exponent))
+        ROUND_MANTISSA_TO_INTEGER(ieee_value, unbiased_exponent); /* Also digits in mantissa low part are significant.  */
+
+    return ieee_value.ld;
+  }
+}
diff -aprNU5 djgpp.orig/src/libm/math/w_remainder.c djgpp/src/libm/math/w_remainder.c
--- djgpp.orig/src/libm/math/w_remainder.c    1997-04-15 08:39:54 +0100
+++ djgpp/src/libm/math/w_remainder.c    2013-11-07 00:38:14 +0100
@@ -11,48 +11,53 @@
   * ====================================================
   */

  /*
  FUNCTION
-<<rint>>, <<rintf>>, <<remainder>>, <<remainderf>>---round and remainder
+<<rint>>, <<rintf>>, <<rintl>>, <<remainder>>, <<remainderf>>---round and remainder
  INDEX
      rint
  INDEX
      rintf
  INDEX
+    rintl
+INDEX
      remainder
  INDEX
      remainderf

  ANSI_SYNOPSIS
      #include <math.h>
      double rint(double <[x]>);
      float rintf(float <[x]>);
+    long double rintl(long double <[x]>);
      double remainder(double <[x]>, double <[y]>);
      float remainderf(float <[x]>, float <[y]>);

  TRAD_SYNOPSIS
      #include <math.h>
      double rint(<[x]>)
      double <[x]>;
      float rintf(<[x]>)
      float <[x]>;
+    long double rint(<[x]>)
+    long double <[x]>;
      double remainder(<[x]>,<[y]>)
      double <[x]>, <[y]>;
      float remainderf(<[x]>,<[y]>)
      float <[x]>, <[y]>;

  DESCRIPTION
-<<rint>> and <<rintf>> returns their argument rounded to the nearest
+<<rint>>, <<rintf>> and <<rintl>> returns their argument rounded to the nearest
  integer.  <<remainder>> and <<remainderf>> find the remainder of
  <[x]>/<[y]>; this value is in the range -<[y]>/2 .. +<[y]>/2.

  RETURNS
  <<rint>> and <<remainder>> return the integer result as a double.

  PORTABILITY
-<<rint>> and <<remainder>> are System V release 4.  <<rintf>> and
+<<rint>> and <<remainder>> are System V release 4.  <<rintf>>, <<rintl>> and
  <<remainderf>> are extensions.

  */

  /*
diff -aprNU5 djgpp.orig/tests/cygnus/main-t.c djgpp/tests/cygnus/main-t.c
--- djgpp.orig/tests/cygnus/main-t.c    2013-10-26 16:19:42 +0100
+++ djgpp/tests/cygnus/main-t.c    2013-11-07 22:40:54 +0100
@@ -40,10 +40,12 @@ int main(void)
    failed += trunc_test(); number_of_functions++;
    printf("Testing truncf...\n");
    failed += truncf_test(); number_of_functions++;
    printf("Testing truncl...\n");
    failed += truncl_test(); number_of_functions++;
+  printf("Testing rintl...\n");
+  failed += rintl_test(); number_of_functions++;

    printf("Tested %d functions, %d errors detected\n", number_of_functions, failed);
    if (!isatty(fileno(stdout)))
      fprintf(stderr, "Tested %d functions, %d errors detected\n", number_of_functions, failed);

diff -aprNU5 djgpp.orig/tests/cygnus/main-t.h djgpp/tests/cygnus/main-t.h
--- djgpp.orig/tests/cygnus/main-t.h    2013-10-26 16:19:48 +0100
+++ djgpp/tests/cygnus/main-t.h    2013-11-07 22:40:56 +0100
@@ -24,7 +24,8 @@ int round_test(void);
  int roundf_test(void);
  int roundl_test(void);
  int trunc_test(void);
  int truncf_test(void);
  int truncl_test(void);
+int rintl_test(void);

  #endif  /* MAIN_T_H */
diff -aprNU5 djgpp.orig/tests/cygnus/makefile djgpp/tests/cygnus/makefile
--- djgpp.orig/tests/cygnus/makefile    2013-10-26 17:18:54 +0100
+++ djgpp/tests/cygnus/makefile    2013-11-07 22:39:06 +0100
@@ -40,11 +40,12 @@ LDFLAGS  = -nostdlib -L$(TOP)/../lib
  OFILES = test.o string.o convert.o conv_vec.o iconv_vec.o test_is.o \
           dvec.o sprint_vec.o sprint_ivec.o math.o math2.o test_ieee.o

  T_OFILES = main-t.o trunc-t.o truncf-t.o truncl-t.o lrint-t.o lrintf-t.o \
             lrintl-t.o llrint-t.o llrintl-t.o roundf-t.o round-t.o roundl-t.o \
-           lroundf-t.o lround-t.o lroundl-t.o llroundf-t.o llround-t.o llroundl-t.o
+           lroundf-t.o lround-t.o lroundl-t.o llroundf-t.o llround-t.o llroundl-t.o \
+           rintl-t.o

  acosVEC_FILES   = acos_vec.c acosf_vec.c
  acoshVEC_FILES  = acosh_vec.c acoshf_vec.c
  asinVEC_FILES   = asin_vec.c asinf_vec.c
  asinhVEC_FILES  = asinh_vec.c asinhf_vec.c
diff -aprNU5 djgpp.orig/tests/cygnus/rintl-t.c djgpp/tests/cygnus/rintl-t.c
--- djgpp.orig/tests/cygnus/rintl-t.c    1970-01-01 01:00:00 +0100
+++ djgpp/tests/cygnus/rintl-t.c    2013-11-07 23:46:02 +0100
@@ -0,0 +1,108 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+
+#include "main-t.h"
+
+static const long_double_t tests_long_double[][2] =
+{
+  /*    value             should be        */
+  /* Zeros. */
+  { { 0x0U, 0x0U, 0x0U, 0 }, { 0x0U, 0x0U, 0x0U, 0 } }, /* 0.0 */
+  { { 0x0U, 0x0U, 0x0U, 1 }, { 0x0U, 0x0U, 0x0U, 1 } }, /* -0.0 */
+
+  /* Subnormals aka denormals. */
+  { { 0x1U, 0x0U, 0x0U, 0 }, { 0x0U, 0x0U, 0x0U, 0 } }, /* Very small number. */
+  { { 0x1U, 0x0U, 0x0U, 1 }, { 0x0U, 0x0U, 0x0U, 1 } }, /* Very small -number. */
+
+  /* Normals. */
+  { { 0x0U, 0x80000000U, 0x1U, 0 }, { 0x0U, 0x0U, 0x0U, 0 } }, /* Small number. */
+  { { 0x0U, 0x80000000U, 0x1U, 1 }, { 0x0U, 0x0U, 0x0U, 1 } }, /* Small -number. */
+  { { 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 0 }, { 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 0 } }, /* Big number. */
+  { { 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 1 }, { 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 1 } }, /* Big -number. */
+
+  /* Infs. */
+  { { 0x0U, 0x80000000U, 0x7FFFU, 0 }, { 0x0U, 0x80000000U, 0x7FFFU, 0 } }, /* Inf */
+  { { 0x0U, 0x80000000U, 0x7FFFU, 1 }, { 0x0U, 0x80000000U, 0x7FFFU, 1 } }, /* -Inf */
+
+  /* NaNs. */
+  { { 0x1U, 0x80000000U, 0x7FFFU, 0 }, { 0x1U, 0xC0000000U, 0x7FFFU, 0 } }, /* SNaN */
+  { { 0x1U, 0x80000000U, 0x7FFFU, 1 }, { 0x1U, 0xC0000000U, 0x7FFFU, 1 } }, /* -SNaN */
+  { { 0x0U, 0xFFFFFFFFU, 0x7FFFU, 0 }, { 0x0U, 0xFFFFFFFFU, 0x7FFFU, 0 } }, /* QNaN */
+  { { 0x0U, 0xFFFFFFFFU, 0x7FFFU, 1 }, { 0x0U, 0xFFFFFFFFU, 0x7FFFU, 1 } }, /* -QNaN */
+
+  /* Number. */
+  { { 0x2168C000U, 0xC90FDAA2U, 0x4000U, 0 }, { 0x0U, 0xC0000000U, 0x4000U, 0 } }, /* PI */
+  { { 0x2168C000U, 0xC90FDAA2U, 0x4000U, 1 }, { 0x0U, 0xC0000000U, 0x4000U, 1 } }, /* -PI */
+
+  /* Different mantissa patterns. */
+  { { 0xFFFFFFFFU, 0xF0000003U, 0x3FFFU + 0x0021U, 0 }, { 0x00000000U, 0xF0000004U, 0x3FFFU + 0x0021U, 0 } }, /* 16106127376.0000000000000000 */
+  { { 0xFFFFFFFFU, 0xF0000003U, 0x3FFFU + 0x0020U, 0 }, { 0x00000000U, 0xF0000004U, 0x3FFFU + 0x0020U, 0 } }, /* 8053063688.0000000000000000 */
+  { { 0xFFFFFFFFU, 0xF0000003U, 0x3FFFU + 0x001FU, 0 }, { 0x00000000U, 0xF0000004U, 0x3FFFU + 0x001FU, 0 } }, /* 4026531844.0000000000000000 */
+  { { 0xFFFFFFFFU, 0xF0000003U, 0x3FFFU + 0x001EU, 0 }, { 0x00000000U, 0xF0000004U, 0x3FFFU + 0x001EU, 0 } }, /* 2013265922.0000000000000000 */
+
+  /*  Number greater than 2**63 thus all digits are significant and will not be truncated.  */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0040U, 0 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0040U, 0 } }, /* 18446744073709551616.0000000000 */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0040U, 1 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0040U, 1 } }, /* 18446744073709551616.0000000000 */
+
+  /*  Number less than 1 thus will be truncated to 0.  */
+  { { 0xB4395810U, 0xFFBE76C8U, 0x3FFFU + 0xFFFFFFFFU, 0 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0000U, 0 } }, /* 0.9990000000 */
+  { { 0xB4395810U, 0xFFBE76C8U, 0x3FFFU + 0xFFFFFFFFU, 1 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0000U, 1 } }, /* -0.9990000000 */
+  { { 0x7F29A800U, 0x800001ADU, 0x3FFFU + 0xFFFFFFFFU, 0 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0000U, 0 } }, /* 0.5000000999999999 */
+  { { 0x7F29A800U, 0x800001ADU, 0x3FFFU + 0xFFFFFFFFU, 1 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0000U, 1 } }, /* -0.5000000999999999 */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0xFFFFFFFFU, 0 }, { 0x0U, 0x0U, 0x0U, 0 } }, /* 0.50000000 */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0xFFFFFFFFU, 1 }, { 0x0U, 0x0U, 0x0U, 1 } }, /* -0.50000000 */
+  { { 0xFA9C12F1U, 0xA1CEF240U, 0x3FFFU + 0xFFFFFFF6U, 0 }, { 0x0U, 0x0U, 0x0U, 0 } }, /* 0.0012345000 */
+  { { 0xFA9C12F1U, 0xA1CEF240U, 0x3FFFU + 0xFFFFFFF6U, 1 }, { 0x0U, 0x0U, 0x0U, 1 } }, /* -0.0012345000 */
+
+  /*  Number less than 2**31 thus all digits in the lower fraction part of the mantissa are insignificant and will be truncated accordingly.  */
+  { { 0x5B9A6800U, 0xFFFFFFFFU, 0x3FFFU + 0x001EU, 0 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x001FU, 0 } }, /* 2147483647.6789124012 */
+  { { 0x5B9A6800U, 0xFFFFFFFFU, 0x3FFFU + 0x001EU, 1 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x001FU, 1 } }, /* -2147483647.6789124012 */
+  { { 0x9988C800U, 0x800056E6U, 0x3FFFU + 0x0010U, 0 }, { 0x00000000U, 0x80008000U, 0x3FFFU + 0x0010U, 0 } }, /* 65536.6789123457 */
+  { { 0x9988C800U, 0x800056E6U, 0x3FFFU + 0x0010U, 1 }, { 0x00000000U, 0x80008000U, 0x3FFFU + 0x0010U, 1 } }, /* -65536.6789123457 */
+  { { 0xF4025800U, 0x800005B1U, 0x3FFFU + 0x0000U, 0 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0000U, 0 } }, /* 1.0000006789 */
+  { { 0xF4025800U, 0x800005B1U, 0x3FFFU + 0x0000U, 1 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x0000U, 1 } }, /* -1.0000006789 */
+
+  /*  Number greather than 2**31 and less than 2**63 thus all digits in the lower and higher fraction part of the mantissa are insignificant and will be truncated accordingly.  */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0x001FU, 0 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x001FU, 0 } }, /* 2147483648.0000000000 */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0x001FU, 1 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x001FU, 1 } }, /* -2147483648.0000000000 */
+  { { 0x00041000U, 0x80000000U, 0x3FFFU + 0x002DU, 0 }, { 0x00040000U, 0x80000000U, 0x3FFFU + 0x002DU, 0 } }, /* 35184372088833.0156250000 */
+  { { 0x00041000U, 0x80000000U, 0x3FFFU + 0x002DU, 1 }, { 0x00040000U, 0x80000000U, 0x3FFFU + 0x002DU, 1 } }, /* -35184372088833.0156250000 */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0x003FU, 0 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x003FU, 0 } }, /* 9223372036854775808.0000000000 */
+  { { 0x00000000U, 0x80000000U, 0x3FFFU + 0x003FU, 1 }, { 0x00000000U, 0x80000000U, 0x3FFFU + 0x003FU, 1 } }, /* -9223372036854775808.0000000000 */
+};
+
+static const size_t n_tests_long_double = sizeof(tests_long_double) / sizeof(tests_long_double[0]);
+
+
+int rintl_test(void)
+{
+  int i, counter;
+
+  for (counter = i = 0; i < n_tests_long_double; i++)
+  {
+    _longdouble_union_t value, result, should_be;
+    value.ldt = tests_long_double[i][0];
+    result.ld = rintl(value.ld);
+    should_be.ldt = tests_long_double[i][1];
+
+    if (should_be.ldt.sign == result.ldt.sign &&
+        should_be.ldt.exponent == result.ldt.exponent &&
+        should_be.ldt.mantissah == result.ldt.mantissah &&
+        should_be.ldt.mantissal == result.ldt.mantissal)
+    {
+      result.ld = truncl(result.ld);
+      if (should_be.ldt.sign == result.ldt.sign &&
+          should_be.ldt.exponent == result.ldt.exponent &&
+          should_be.ldt.mantissah == result.ldt.mantissah &&
+          should_be.ldt.mantissal == result.ldt.mantissal)
+        counter++;
+      else
+        printf("rintl test failed:  value to truncate = %.12Lf result = %.12Lf  should be = %.12Lf\n", value.ld, result.ld, should_be.ld);
+    }
+    else
+      printf("rintl test failed:  value to truncate = %.12Lf result = %.12Lf  should be = %.12Lf\n", value.ld, result.ld, should_be.ld);
+  }
+  printf("%s\n", (counter < n_tests_long_double) ? "rintl test failed." : "rintl test succeded.");
+
+  return (counter < n_tests_long_double) ? 1 : 0;
+}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019