delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2013/10/23/18:32:52

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
Message-ID: <52684DC7.1010002@gmx.de>
Date: Thu, 24 Oct 2013 00:29:27 +0200
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: Re: Implementation of the round[f|l] family of functions.
References: <524B7666 DOT 9060701 AT gmx DOT de>
In-Reply-To: <524B7666.9060701@gmx.de>
X-Provags-ID: V03:K0:+v8QsYipTF/EDbVdiV8wgS7F6CH7fbxUKlAxg1A5xMew3gbtSmx
u6Vl4v0ulC5Erp7bPW6SuWHTZ8UJRSlfPyH1VSqbfDef9b4kdXyS5Lmw0T6eQRSZ4Sn5MwO
UqkZSYrp7YxhZC/r8SMtxeCLCU4lXA2L5bEC45ckCviHlvAL4omNNC+115Mt54w5mQmCqJE
xhQzEynx9WIWYf6uXBNJQ==
Reply-To: djgpp-workers AT delorie DOT com

Am 02.10.2013 03:27, schrieb Juan Manuel Guerrero:
> Below is a patch that shall provide the implementation of the round[f|l]
> family of functions in libm.a.  Some test cases have been added. I have
> compiled and tested the code with gcc473 and the djcross-gcc481.
> As usual suggestions, objections and comments are welcome.
[snip]

OFYI, I committed the patch below.

Regards,

Juan M. Guerrero



2013-10-01  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


     * djgpp/src/docs/kb/wc204.txi: Info about round[f|l] family of functions added.


2013-09-29  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


     * djgpp/tests/cygnus/t-round.c: Check for round.

     * djgpp/tests/cygnus/t-roundl.c: Check for roundl.

     * djgpp/tests/cygnus/makefile: round[l] added to goal list.


2013-09-28  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


     * djgpp/include/math.h: Prototype of roundl added.

     * djgpp/include/libm/math.h: Prototype of roundl added.

     * djgpp/src/libm/math/roundl.c: Implementation of roundl.

     * djgpp/src/libm/math/makefile: roundl added to goal list.


2013-09-22  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


     * djgpp/include/math.h: Prototype of round[f] added.

     * djgpp/include/libm/math.h: Prototype of round[f] added.

     * djgpp/src/libm/math/round.c: Implementation of round.

     * djgpp/src/libm/math/roundf.c: Implementation of roundf.

     * djgpp/src/libm/math/makefile: round[f] added to goal list.

     * djgpp/src/libm/math/math.texi: Entry of round[f|l] functions added.

     * djgpp/tests/cygnus/t-roundf.c: Check for roundf.

     * djgpp/tests/cygnus/makefile: roundf added to goal list.





diff -aprNU5 djgpp.orig/include/libm/math.h djgpp/include/libm/math.h
--- djgpp.orig/include/libm/math.h    2013-10-20 13:57:04 +0100
+++ djgpp/include/libm/math.h    2013-10-23 21:58:36 +0100
@@ -162,10 +162,13 @@ extern long long int llrintf __P((float)
  extern long long int llrint __P((double));
  extern long long int llrintl __P((long double));
  extern long int lrintf __P((float));
  extern long int lrint __P((double));
  extern long int lrintl __P((long double));
+extern float roundf __P((float));
+extern double round __P((double));
+extern long double roundl __P((long double));
  extern float truncf __P((float));
  extern double trunc __P((double));
  extern long double truncl __P((long double));
  #endif /* !defined (__STRICT_ANSI__) || defined(__cplusplus)
            || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L */
diff -aprNU5 djgpp.orig/include/math.h djgpp/include/math.h
--- djgpp.orig/include/math.h    2013-10-20 13:57:06 +0100
+++ djgpp/include/math.h    2013-10-23 21:58:36 +0100
@@ -193,10 +193,12 @@ extern double trunc(double);
  extern long double truncl(long double);
  extern long int lrint(double);
  extern long int lrintl(long double);
  extern long long int llrint(double);
  extern long long int llrintl(long double);
+extern double round(double);
+extern long double roundl(long double);
  extern float erff(float);
  extern float erfcf(float);
  extern float hypotf(float, float);
  extern float lgammaf(float);
  extern float acoshf(float);
@@ -214,10 +216,11 @@ extern float scalbnf(float, int);
  extern float expm1f(float);
  extern float log1pf(float);
  extern float truncf(float);
  extern long int lrintf(float);
  extern long long int llrintf(float);
+extern float roundf(float);

  /* End libm.a. */

  #endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */

diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi    2013-10-20 13:57:08 +0100
+++ djgpp/src/docs/kb/wc204.txi    2013-10-23 21:58:36 +0100
@@ -1320,5 +1320,12 @@ set an error indicator.  This error indi
  @findex llrintl AT r{ added}
  The @acronym{C99} functions @code{lrintf}, @code{lrint}, @code{lrintl}, @code{llrintf},
  @code{llrint} and @code{llrintl} were added to comply with the @acronym{C99} standard.
  These functions are available in two versions.  One fast assembler version
  in @file{libc.a} and one accurate in @file{libm.a}.
+
+@cindex @acronym{C99} compliance, @code{math.h}
+@findex roundf AT r{ added}
+@findex round AT r{ added}
+@findex roundl AT r{ added}
+The @acronym{C99} functions @code{roundf}, @code{round} and @code{roundl} were added
+to comply with the @acronym{C99} standard.
diff -aprNU5 djgpp.orig/src/libm/math/makefile djgpp/src/libm/math/makefile
--- djgpp.orig/src/libm/math/makefile    2013-10-20 13:57:12 +0100
+++ djgpp/src/libm/math/makefile    2013-10-23 21:58:36 +0100
@@ -171,10 +171,13 @@ SRC += lrint.c
  SRC += lrintf.c
  SRC += lrintl.c
  SRC += llrint.c
  SRC += llrintf.c
  SRC += llrintl.c
+SRC += round.c
+SRC += roundf.c
+SRC += roundl.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 \
@@ -182,11 +185,11 @@ chobj = w_acos.def w_acosh.def w_asin.de
      w_log10.def s_log1p.def s_matherr.def s_modf.def \
      w_pow.def w_remainder.def s_sin.def w_sinh.def \
      s_cbrt.def w_sqrt.def s_tan.def s_tanh.def \
      s_infinity.def s_isnan.def s_scalbn.def s_nextafter.def \
      s_nan.def s_ilogb.def s_expm1.def trunc.def \
-    lrint.def llrint.def
+    lrint.def llrint.def round.def

  CFLAGS = -D_USE_LIBM_MATH_H
  EXTRA_FILES = $(TOP)/../../info/libm.info
  # chew emits non-fatal warnings, so we redirect them to the void
  CHEW = ./chew.exe -f ./doc.str -e /dev/null
diff -aprNU5 djgpp.orig/src/libm/math/math.texi djgpp/src/libm/math/math.texi
--- djgpp.orig/src/libm/math/math.texi    2013-10-20 13:57:14 +0100
+++ djgpp/src/libm/math/math.texi    2013-10-23 21:58:36 +0100
@@ -62,10 +62,11 @@ available when you include @file{math.h}
  * modf::    Split fractional and integer parts
  * nan::        Floating Not a Number
  * nextafter::    Get next representable number
  * pow::        X to the power Y
  * rint::    Round and  remainder (rint, remainder)
+* round::    Round to integer, away from zero
  * scalbn::    Scale number
  * sin::        Sine or cosine (sin, cos)
  * sinh::    Hyperbolic sine
  * sqrt::    Positive square root
  * tan::        Tangent
@@ -232,5 +233,8 @@ The library is set to X/Open mode by def
  @page
  @include lrint.def

  @page
  @include llrint.def
+
+@page
+@include round.def
diff -aprNU5 djgpp.orig/src/libm/math/round.c djgpp/src/libm/math/round.c
--- djgpp.orig/src/libm/math/round.c    1970-01-01 01:00:00 +0100
+++ djgpp/src/libm/math/round.c    2013-10-23 21:58:36 +0100
@@ -0,0 +1,130 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+/*
+FUNCTION
+<<round>>, <<roundf>>, <<roundl>>--round to nearest integer
+INDEX
+    round
+INDEX
+    roundf
+INDEX
+    roundl
+
+ANSI_SYNOPSIS
+        #include <math.h>
+        double round(double <[x]>);
+        float roundf(float <[x]>);
+        long double round(long double <[x]>);
+
+DESCRIPTION
+        The <<round>> functions round their argument to the nearest integer
+        value in floating-point format, rounding halfway cases away from zero,
+        regardless of the current rounding direction.  (While the "inexact"
+        floating-point exception behavior is unspecified by the C standard, the
+        <<round>> functions are written so that "inexact" is not raised if the
+        result does not equal the argument, which behavior is as recommended by
+        IEEE 754 for its related functions.)
+
+RETURNS
+        <[x]> rounded to an integral value.
+
+PORTABILITY
+ANSI C, POSIX
+
+*/
+
+#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 DOUBLE_BIAS (0x3FFU)
+#define MAX_BIN_EXPONENT                                    (1023)
+#define MIN_BIN_EXPONENT                                    (-1022)
+#define BIN_DIGITS_IN_FRACTION                              (52) /*  Amount of binary digits in fraction part of mantissa.  */
+#define BIN_DIGITS_IN_MANTISSAH                             (20) /*  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 MAGNITUDE_IS_GREATER_THAN_ONE_HALF(exp)             ((exp) == -1)
+#define IS_INF_OR_NAN(exp)                                  ((exp) > MAX_BIN_EXPONENT)
+
+#define SIGNIFICANT_FRACTION_DIGITS_MASK(exp) (0xFFFFFFFFUL >> ((exp) - BIN_DIGITS_IN_MANTISSAH))
+#define IS_INTEGRAL(num, unbiased_exponent) (((num).dt.mantissal & SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent)) == 0)
+
+#define CARRY_INTO_INTEGER_PART(x)                          ((x) & 0x00100000UL)
+#define MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(exp) (0x000FFFFFUL >> (exp))
+#define IS_MANTISSAH_INTEGRAL(num, unbiased_exponent) ((((num).dt.mantissah & MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent)) == 0) && ((num).dt.mantissal == 0))
+#define ROUND_MANTISSAH_TO_INTEGER(num, unbiased_exponent) \
+(__gnuc_extension__ \
+ ({ \
+     uint64_t rounded_mantissa = (uint64_t)(num).dt.mantissah + (0x00080000UL >> (unbiased_exponent));        \
+     (num).dt.mantissah = rounded_mantissa & ~MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent);  \
+     (num).dt.mantissal = 0; \
+     (num).dt.exponent += (rounded_mantissa & ~0x000FFFFUL) >> BIN_DIGITS_IN_MANTISSAH;                       \
+ }) \
+)
+#define ROUND_MANTISSA_TO_INTEGER(num, unbiased_exponent) \
+(__gnuc_extension__ \
+ ({ \
+     const uint32_t rounded_mantissal = (uint32_t)(num).dt.mantissal + (1UL << (BIN_DIGITS_IN_FRACTION - 1 - (unbiased_exponent)));  \
+ \
+      if (rounded_mantissal < (num).dt.mantissal) \
+ { \
+        const uint32_t result = (uint32_t)(num).dt.mantissah + 1; /* Carry from rounded mantissal.  */                              \
+ \
+        if (CARRY_INTO_INTEGER_PART(result)) \
+          (num).dt.exponent += 1;  /* Carry from rounded mantissal. */                                                              \
+        (num).dt.mantissah = result; \
+ } \
+      (num).dt.mantissal = rounded_mantissal & ~SIGNIFICANT_FRACTION_DIGITS_MASK((unbiased_exponent)); \
+ }) \
+)
+
+
+#ifdef __STDC__
+double
+round(double x)
+#else
+double
+round(x)
+double x;
+#endif
+{
+  _double_union_t ieee_value;
+  int unbiased_exponent;
+
+
+  ieee_value.d = x;
+  unbiased_exponent = ieee_value.dt.exponent - 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))
+    {
+      const int sign = ieee_value.dt.sign;
+      ieee_value.d = MAGNITUDE_IS_GREATER_THAN_ONE_HALF(unbiased_exponent) ? 1 : 0;
+      ieee_value.dt.sign = sign;
+    }
+    else if (!IS_MANTISSAH_INTEGRAL(ieee_value, unbiased_exponent))
+      ROUND_MANTISSAH_TO_INTEGER(ieee_value, unbiased_exponent);
+
+    return ieee_value.d;
+  }
+  else
+  {
+    /* Also digits in mantissa low part are significant.  */
+    if (!IS_INTEGRAL(ieee_value, unbiased_exponent))
+      ROUND_MANTISSA_TO_INTEGER(ieee_value, unbiased_exponent);
+
+    return ieee_value.d;
+  }
+}
diff -aprNU5 djgpp.orig/src/libm/math/roundf.c djgpp/src/libm/math/roundf.c
--- djgpp.orig/src/libm/math/roundf.c    1970-01-01 01:00:00 +0100
+++ djgpp/src/libm/math/roundf.c    2013-10-23 21:58:36 +0100
@@ -0,0 +1,65 @@
+/* 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 FLOAT_BIAS                                (0x7FU)
+#define BIN_DIGITS_IN_FRACTION                    (23)    /* Amount of binary digits in fraction part of mantissa.  */
+#define MAX_BIN_EXPONENT                          (127)
+#define MIN_BIN_EXPONENT                          (-126)
+#define ALL_DIGITS_ARE_SIGNIFICANT(exp)           ((exp) > (BIN_DIGITS_IN_FRACTION - 1))
+#define MAGNITUDE_IS_LESS_THAN_ONE(exp)           ((exp) < 0)
+#define MAGNITUDE_IS_GREATER_THAN_ONE_HALF(exp)   ((exp) == -1)
+#define IS_INF_OR_NAN(exp)                        ((exp) > MAX_BIN_EXPONENT)
+
+#define SIGNIFICANT_FRACTION_DIGITS_MASK(exp)     (0x007FFFFFUL >> (exp))
+#define IS_INTEGRAL(num, unbiased_exponent) (((num).ft.mantissa & SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent)) == 0)
+#define ROUND_TO_INTEGER(num, unbiased_exponent) \
+(__gnuc_extension__ \
+ ({ \
+     uint32_t rounded_mantissa = (uint32_t)(num).ft.mantissa + (0x00400000UL >> (unbiased_exponent));  \
+     (num).ft.mantissa = rounded_mantissa & ~SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent);      \
+     (num).ft.exponent += (rounded_mantissa & ~0x007FFFFFUL) >> BIN_DIGITS_IN_FRACTION;                \
+ }) \
+)
+
+
+#ifdef __STDC__
+float
+roundf(float x)
+#else
+float
+roundf(x)
+float x;
+#endif
+{
+  _float_union_t ieee_value;
+  int unbiased_exponent;
+
+
+  ieee_value.f = x;
+  unbiased_exponent = ieee_value.ft.exponent - FLOAT_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 (MAGNITUDE_IS_LESS_THAN_ONE(unbiased_exponent))
+    {
+      const int sign = ieee_value.ft.sign;
+      ieee_value.f = MAGNITUDE_IS_GREATER_THAN_ONE_HALF(unbiased_exponent) ? 1 : 0;
+      ieee_value.ft.sign = sign;
+    }
+    else if (!IS_INTEGRAL(ieee_value, unbiased_exponent))
+      ROUND_TO_INTEGER(ieee_value, unbiased_exponent);
+
+    return ieee_value.f;
+  }
+}
diff -aprNU5 djgpp.orig/src/libm/math/roundl.c djgpp/src/libm/math/roundl.c
--- djgpp.orig/src/libm/math/roundl.c    1970-01-01 01:00:00 +0100
+++ djgpp/src/libm/math/roundl.c    2013-10-23 21:58:36 +0100
@@ -0,0 +1,95 @@
+/* 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 MAGNITUDE_IS_GREATER_THAN_ONE_HALF(exp)             ((exp) == -1)
+#define IS_INF_OR_NAN(exp)                                  ((exp) > MAX_BIN_EXPONENT)
+
+#define SIGNIFICANT_FRACTION_DIGITS_MASK(exp) (0xFFFFFFFFUL >> ((exp) - BIN_DIGITS_IN_MANTISSAH))
+#define IS_INTEGRAL(num, unbiased_exponent) (((num).ldt.mantissal & SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent)) == 0)
+
+#define CARRY_INTO_INTEGER_PART(x)                          ((x) & 0x100000000ULL)
+#define MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(exp) (0x7FFFFFFFUL >> (exp))
+#define IS_MANTISSAH_INTEGRAL(num, unbiased_exponent) ((((num).ldt.mantissah & MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent)) == 0) && ((num).ldt.mantissal == 0))
+#define ROUND_MANTISSAH_TO_INTEGER(num, unbiased_exponent) \
+(__gnuc_extension__ \
+ ({ \
+     uint64_t rounded_mantissa = (uint64_t)(num).ldt.mantissah + (0x40000000ULL >> (unbiased_exponent));       \
+     if (CARRY_INTO_INTEGER_PART(rounded_mantissa)) \
+ { \
+       rounded_mantissa >>= 1; \
+       (num).ldt.exponent += 1; \
+ } \
+     (num).ldt.mantissah = rounded_mantissa & ~MANTISSAH_SIGNIFICANT_FRACTION_DIGITS_MASK(unbiased_exponent);  \
+     (num).ldt.mantissal = 0; \
+ }) \
+)
+#define ROUND_MANTISSA_TO_INTEGER(num, unbiased_exponent) \
+(__gnuc_extension__ \
+ ({ \
+     const uint32_t rounded_mantissal = (num).ldt.mantissal + (1UL << (BIN_DIGITS_IN_FRACTION - 1 - (unbiased_exponent)));  \
+ \
+     if (rounded_mantissal < (num).ldt.mantissal) \
+       (num).ldt.mantissah += 1;  /* Carry from rounded mantissal. */                                                      \
+     (num).ldt.mantissal = rounded_mantissal & ~SIGNIFICANT_FRACTION_DIGITS_MASK((unbiased_exponent)); \
+ }) \
+)
+
+
+#ifdef __STDC__
+long double
+roundl(long double x)
+#else
+long double
+round(x)
+long double x;
+#endif
+{
+  _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))
+    {
+      const int sign = ieee_value.ldt.sign;
+      ieee_value.ld = MAGNITUDE_IS_GREATER_THAN_ONE_HALF(unbiased_exponent) ? 1 : 0;
+      ieee_value.ldt.sign = sign;
+    }
+    else if (!IS_MANTISSAH_INTEGRAL(ieee_value, unbiased_exponent))
+      ROUND_MANTISSAH_TO_INTEGER(ieee_value, unbiased_exponent);
+
+    return ieee_value.ld;
+  }
+  else
+  {
+    /* Also digits in mantissa low part are significant.  */
+    if (!IS_INTEGRAL(ieee_value, unbiased_exponent))
+      ROUND_MANTISSA_TO_INTEGER(ieee_value, unbiased_exponent);
+
+    return ieee_value.ld;
+  }
+}
diff -aprNU5 djgpp.orig/tests/cygnus/makefile djgpp/tests/cygnus/makefile
--- djgpp.orig/tests/cygnus/makefile    2013-10-20 13:57:16 +0100
+++ djgpp/tests/cygnus/makefile    2013-10-23 21:58:36 +0100
@@ -92,20 +92,24 @@ VEC_OFILES = $(GEN_VEC_FILES:.c=.o)

  $(OFILES): CFLAGS = $(DEFS) -fno-builtin -O2 -g -Wall

  all: check

-check: mtest.exe t-trunc.exe t-truncf.exe t-truncl.exe t-lrint.exe t-lrintf.exe t-lrintl.exe t-llrint.exe t-llrintl.exe
+check: mtest.exe t-trunc.exe t-truncf.exe t-truncl.exe t-lrint.exe t-lrintf.exe t-lrintl.exe t-llrint.exe t-llrintl.exe \
+       t-roundf.exe t-round.exe t-roundl.exe
      ./mtest.exe > mtest.results
      ./t-trunc.exe > ttest.results
      ./t-truncf.exe >> ttest.results
      ./t-truncl.exe >> ttest.results
      ./t-lrintf.exe >> ttest.results
      ./t-lrint.exe >> ttest.results
      ./t-lrintl.exe >> ttest.results
      ./t-llrint.exe >> ttest.results
      ./t-llrintl.exe >> ttest.results
+    ./t-roundf.exe >> ttest.results
+    ./t-round.exe >> ttest.results
+    ./t-roundl.exe >> ttest.results

  # Pattern rules to generate test vectors.  (The funky vec.c=%.c replacement
  # is meant to create a pattern rule where actually a normal rule will
  # do, since only pattern rules can tell Make that several targets are
  # generated all at once.  Without this, Make will invoke the vector-
@@ -155,13 +159,22 @@ t-llrint.exe: t-llrint.o
      $(CC) -o $@ $(LDFLAGS) t-llrint.o $(LIBS)

  t-llrintl.exe: t-llrintl.o
      $(CC) -o $@ $(LDFLAGS) t-llrintl.o $(LIBS)

+t-roundf.exe: t-roundf.o
+    $(CC) -o $@ $(LDFLAGS) t-roundf.o $(LIBS)
+
+t-round.exe: t-round.o
+    $(CC) -o $@ $(LDFLAGS) t-round.o $(LIBS)
+
+t-roundl.exe: t-roundl.o
+    $(CC) -o $@ $(LDFLAGS) t-roundl.o $(LIBS)
+
  $(OFILES) $(VEC_OFILES) : test.h

  clean mostlyclean:
      -cd tgen; $(MAKE) $@
-    cd $(HERE); $(RM) $(OFILES) $(VEC_OFILES) *~ *.exe mtest.results ttest.results t-trunc*.o t-lrint*.o t-llrint*.o
+    cd $(HERE); $(RM) $(OFILES) $(VEC_OFILES) *~ *.exe mtest.results ttest.results t-trunc*.o t-lrint*.o t-llrint*.o t-round*.o

  .SECONDARY: $(GEN_PROGS) $(GEN_VEC_FILES)
  .PHONY: all check clean mostlyclean
diff -aprNU5 djgpp.orig/tests/cygnus/t-round.c djgpp/tests/cygnus/t-round.c
--- djgpp.orig/tests/cygnus/t-round.c    1970-01-01 01:00:00 +0100
+++ djgpp/tests/cygnus/t-round.c    2013-10-23 21:58:36 +0100
@@ -0,0 +1,121 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+
+#include <stdio.h>
+#include <math.h>
+#include <libc/ieee.h>
+
+typedef struct {
+  const _double_union_t value;      /* test value */
+  const _double_union_t should_be;  /* result */
+} entry_t;
+
+static const entry_t tests_double[] =
+{
+  /* test value */
+  /*     value           should be   */
+
+  /* Zeros. */
+  {{.dt = {0x0U, 0x0U, 0x0U, 0}},  {0}}, /* 0.0 */
+  {{.dt = {0x0U, 0x0U, 0x0U, 1}},  {0}}, /* -0.0 */
+
+  /* Subnormals aka denormals. */
+  {{.dt = {0x1U, 0x0U, 0x0U, 0}},  {0}}, /* Very small number. */
+  {{.dt = {0x1U, 0x0U, 0x0U, 1}},  {0}}, /* Very small -number. */
+
+  /* Normals. */
+  {{.dt = {0x1U, 0x0U, 0x1U, 0}},  {0}}, /* Small number. */
+  {{.dt = {0x1U, 0x0U, 0x1U, 1}},  {0}}, /* Small -number. */
+  {{.dt = {0xFFFFFFFFU, 0x7FFFFU, 0x7FEU, 0}},  {.dt = {0xFFFFFFFFU, 0x7FFFFU, 0x7FEU, 0}}}, /* Big number. */
+  {{.dt = {0xFFFFFFFFU, 0x7FFFFU, 0x7FEU, 1}},  {.dt = {0xFFFFFFFFU, 0x7FFFFU, 0x7FEU, 1}}}, /* Big -number. */
+
+  /* Infs. */
+  {{.dt = {0x0U, 0x0U, 0x7FFU, 0}},  {.dt = {0x0U, 0x0U, 0x7FFU, 0}}}, /* Inf */
+  {{.dt = {0x0U, 0x0U, 0x7FFU, 1}},  {.dt = {0x0U, 0x0U, 0x7FFU, 1}}}, /* -Inf */
+
+  /* NaNs. */
+  {{.dt = {0x1U, 0x0U, 0x7FFU, 0}},  {.dt = {0x1U, 0x0U, 0x7FFU, 0}}}, /* SNaN */
+  {{.dt = {0x1U, 0x0U, 0x7FFU, 1}},  {.dt = {0x1U, 0x0U, 0x7FFU, 1}}}, /* -SNaN */
+  {{.dt = {0x0U, 0xFFFFFU, 0x7FFU, 0}},  {.dt = {0x0U, 0xFFFFFU, 0x7FFU, 0}}}, /* QNaN */
+  {{.dt = {0x0U, 0xFFFFFU, 0x7FFU, 1}},  {.dt = {0x0U, 0xFFFFFU, 0x7FFU, 1}}}, /* -QNaN */
+
+
+  /* Number. */
+  {{.dt = {0x54442D18U, 0x921FBU, 0x3FFU + 0x001U, 0}},  {+3}}, /* PI */
+  {{.dt = {0x54442D18U, 0x921FBU, 0x3FFU + 0x001U, 1}},  {-3}}, /* -PI */
+
+  {{.dt = {0x00000000U, 0xE0000U, 0x3FFU + 0x0U, 0}},  {+2}}, /* 1.875000 */
+  {{.dt = {0x00000000U, 0xE0000U, 0x3FFU + 0x0U, 1}},  {-2}}, /* -1.875000 */
+  {{.dt = {0x00000000U, 0xA0000U, 0x3FFU + 0x0U, 0}},  {+2}}, /* 1.625000 */
+  {{.dt = {0x00000000U, 0xA0000U, 0x3FFU + 0x0U, 1}},  {-2}}, /* -1.625000 */
+  {{.dt = {0x18DEF417U, 0x80002U, 0x3FFU + 0x0U, 0}},  {+2}}, /* 1.500002 */
+  {{.dt = {0x18DEF417U, 0x80002U, 0x3FFU + 0x0U, 1}},  {-2}}, /* -1.500002 */
+  {{.dt = {0x00000000U, 0x80000U, 0x3FFU + 0x0U, 0}},  {+2}}, /* 1.500000 */
+  {{.dt = {0x00000000U, 0x80000U, 0x3FFU + 0x0U, 1}},  {-2}}, /* -1.500000 */
+  {{.dt = {0xE7210BE9U, 0x7F9FDU, 0x3FFU + 0x0U, 0}},  {+1}}, /* 1.499998 */
+  {{.dt = {0xE7210BE9U, 0x7F9FDU, 0x3FFU + 0x0U, 1}},  {-1}}, /* -1.499998 */
+  {{.dt = {0x00000000U, 0x60000U, 0x3FFU + 0x0U, 0}},  {+1}}, /* 1.375000 */
+  {{.dt = {0x00000000U, 0x60000U, 0x3FFU + 0x0U, 1}},  {-1}}, /* -1.375000 */
+  {{.dt = {0x00000000U, 0x20000U, 0x3FFU + 0x0U, 0}},  {+1}}, /* 1.125000 */
+  {{.dt = {0x00000000U, 0x20000U, 0x3FFU + 0x0U, 1}},  {-1}}, /* -1.125000 */
+
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x016U, 0}}, {+4194304}}, /* 4194304.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x016U, 1}}, {-4194304}}, /* -4194304.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x017U, 0}}, {+8388608}}, /* 8388608.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x017U, 1}}, {-8388608}}, /* -8388608.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x018U, 0}}, {+16777216}}, /* 16777216.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x018U, 1}}, {-16777216}}, /* -16777216.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x01EU, 0}}, {+1073741824}}, /* 1073741824.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x01EU, 1}}, {-1073741824}}, /* -1073741824.000000 */
+  {{.dt = {0xFFC00000U, 0xFFFFFU, 0x3FFU + 0x01EU, 0}}, {+2147483647LL}}, /* 2147483647.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x01FU, 1}}, {-2147483648LL}}, /* -2147483648.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x020U, 0}}, {+4294967296}}, /* 4294967296.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x020U, 1}}, {-4294967296}}, /* -4294967296.000000 */
+  {{.dt = {0xACF13400U, 0x02468U, 0x3FFU + 0x033U, 0}}, {2271815812028928}}, /* 2271815812028928.000000 */
+  {{.dt = {0xACF13400U, 0x02468U, 0x3FFU + 0x033U, 1}}, {-2271815812028928}}, /* -2271815812028928.000000 */
+  {{.dt = {0x56789AB0U, 0x01234U, 0x3FFU + 0x034U, 0}}, {4523615625714352}}, /* 4523615625714352.000000 */
+  {{.dt = {0x56789AB0U, 0x01234U, 0x3FFU + 0x034U, 1}}, {-4523615625714352}}, /* -4523615625714352.000000 */
+  {{.dt = {0xA9876543U, 0xFEDCBU, 0x3FFU + 0x034U, 0}}, {8987183256397123}}, /* 8987183256397123.000000 */
+  {{.dt = {0xA9876543U, 0xFEDCBU, 0x3FFU + 0x034U, 1}}, {-8987183256397123}}, /* -8987183256397123.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x035U, 0}}, {9007199254740992}}, /* 9007199254740992.000000 */
+  {{.dt = {0x00000000U, 0x00000U, 0x3FFU + 0x035U, 1}}, {-9007199254740992}}, /* -9007199254740992.000000 */
+  {{.dt = {0x6789ABCEU, 0x12345U, 0x3FFU + 0x035U, 0}}, {9647711201744796}}, /* 9647711201744796.000000 */
+  {{.dt = {0x6789ABCEU, 0x12345U, 0x3FFU + 0x035U, 1}}, {-9647711201744796}}, /* -9647711201744796.000000 */
+
+  {{.dt = {0x0000F000U, 0xFFFFEU, 0x3FFU + 0x014U, 0}}, {+2097150}}, /* 2097150.000014 */
+  {{.dt = {0x7000F000U, 0xFFFFEU, 0x3FFU + 0x014U, 0}}, {+2097150}}, /* 2097150.437514 */
+  {{.dt = {0x90000000U, 0xFFFFEU, 0x3FFU + 0x014U, 0}}, {+2097151}}, /* 2097150.562500 */
+  {{.dt = {0xE0000000U, 0xFFFFEU, 0x3FFU + 0x014U, 0}}, {+2097151}}, /* 2097150.875000 */
+  {{.dt = {0xE0000000U, 0xFFFFFU, 0x3FFU + 0x014U, 0}}, {+2097152}}, /* 2097151.875000 */
+  {{.dt = {0xF0000000U, 0xFFFFFU, 0x3FFU + 0x014U, 0}}, {+2097152}}, /* 2097151.937500 */
+
+  {{.dt = {0x0000FFFDU, 0xFFFFEU, 0x3FFU + 0x032U, 0}}, {+2251797666217983}}, /* 2251797666217983.250000 */
+  {{.dt = {0x7777777AU, 0xFFFFEU, 0x3FFU + 0x032U, 0}}, {+2251798167281119}}, /* 2251798167281119.500000 */
+  {{.dt = {0x9EEEEEE0U, 0xFFFFEU, 0x3FFU + 0x032U, 0}}, {+2251798332816312}}, /* 2251798332816312.000000 */
+  {{.dt = {0xEEEEEEE7U, 0xFFFFEU, 0x3FFU + 0x032U, 0}}, {+2251798668360634}}, /* 2251798668360634.750000 */
+  {{.dt = {0xEEEEEEEEU, 0xFFFFFU, 0x3FFU + 0x032U, 0}}, {+2251799742102460}}, /* 2251799742102460.500000 */
+  {{.dt = {0xFFFFFFFDU, 0xFFFFFU, 0x3FFU + 0x032U, 0}}, {+2251799813685247}} /* 2251799813685247.250000 */
+};
+
+static const size_t n_tests_double = sizeof(tests_double) / sizeof(tests_double[0]);
+
+
+int main(void)
+{
+  unsigned int i, counter;
+
+  for (counter = i = 0; i < n_tests_double; i++)
+  {
+    double result = round(tests_double[i].value.d);
+
+    if (tests_double[i].should_be.d == result)
+      counter++;
+    else if ((i >= 10 || i <= 13) && isnan(result))
+      counter++;
+    else
+      printf("round test failed:  value to round = %.12f  result = %.12f  should be = %.12f\n", tests_double[i].value.d, result, tests_double[i].should_be.d);
+  }
+  printf("%s\n", (counter < n_tests_double) ? "round test failed." : "round test succeded.");
+
+  return 0;
+}
diff -aprNU5 djgpp.orig/tests/cygnus/t-roundf.c djgpp/tests/cygnus/t-roundf.c
--- djgpp.orig/tests/cygnus/t-roundf.c    1970-01-01 01:00:00 +0100
+++ djgpp/tests/cygnus/t-roundf.c    2013-10-23 21:58:36 +0100
@@ -0,0 +1,105 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+
+#include <stdio.h>
+#include <math.h>
+#include <libc/ieee.h>
+
+typedef struct {
+  const _float_union_t value;      /* test value */
+  const _float_union_t should_be;  /* result */
+} entry_t;
+
+static const entry_t tests_float[] =
+{
+  /* test value */
+  /*     value           should be   */
+
+  /* Zeros. */
+  {{.ft = {0x0U, 0x0U, 0}},   {0}}, /* 0.0 */
+  {{.ft = {0x0U, 0x0U, 1}},   {-0}}, /* -0.0 */
+
+  /* Subnormals aka denormals. */
+  {{.ft = {0x1U, 0x0U, 0}},   {0}}, /* Very small number. */
+  {{.ft = {0x1U, 0x0U, 1}},   {-0}}, /* Very small -number. */
+
+  /* Normals. */
+  {{.ft = {0x1U, 0x1U, 0}},   {0}}, /* Small number. */
+  {{.ft = {0x1U, 0x1U, 1}},   {-0}}, /* Small -number. */
+  {{.ft = {0xFFFFU, 0xFEU, 0}}, {1.71470391173844543952920686828913164288E+38}}, /* Big number. */
+  {{.ft = {0xFFFFU, 0xFEU, 1}}, {-1.71470391173844543952920686828913164288E+38}}, /* Big -number. */
+
+  /* Infs. */
+  {{.ft = {0x0U, 0xFFU, 0}},   {.ft = {0x0U, 0xFFU, 0}}}, /* Inf */
+  {{.ft = {0x0U, 0xFFU, 1}},   {.ft = {0x0U, 0xFFU, 1}}}, /* -Inf */
+
+  /* NaNs. */
+  {{.ft = {0x1U, 0xFFU, 0}},   {.ft = {0x1U, 0xFFU, 0}}}, /* SNaN */
+  {{.ft = {0x1U, 0xFFU, 1}},   {.ft = {0x1U, 0xFFU, 1}}}, /* -SNaN */
+  {{.ft = {0x7FFFFFU, 0xFFU, 0}},   {.ft = {0x7FFFFFU, 0xFFU, 0}}}, /* QNaN */
+  {{.ft = {0x7FFFFFU, 0xFFU, 1}},   {.ft = {0x7FFFFFU, 0xFFU, 1}}}, /* -QNaN */
+
+  /* Numbers. */
+  {{.ft = {0x490FDBU, 0x80U, 0}},  {+3}}, /* PI */
+  {{.ft = {0x490FDBU, 0x80U, 1}},  {-3}}, /* -PI */
+
+  {{.ft = {0x700000U, 0x7FU, 0}},  {+2}}, /* 1.875000 */
+  {{.ft = {0x700000U, 0x7FU, 1}},  {-2}}, /* -1.875000 */
+  {{.ft = {0x500000U, 0x7FU, 0}},  {+2}}, /* 1.625000 */
+  {{.ft = {0x500000U, 0x7FU, 1}},  {-2}}, /* -1.625000 */
+  {{.ft = {0x40000FU, 0x7FU, 0}},  {+2}}, /* 1.500002 */
+  {{.ft = {0x40000FU, 0x7FU, 1}},  {-2}}, /* -1.500002 */
+  {{.ft = {0x400000U, 0x7FU, 0}},  {+2}}, /* 1.500000 */
+  {{.ft = {0x400000U, 0x7FU, 1}},  {-2}}, /* -1.500000 */
+  {{.ft = {0x3FFFF0U, 0x7FU, 0}},  {+1}}, /* 1.499998 */
+  {{.ft = {0x3FFFF0U, 0x7FU, 1}},  {-1}}, /* -1.499998 */
+  {{.ft = {0x300000U, 0x7FU, 0}},  {+1}}, /* 1.375000 */
+  {{.ft = {0x300000U, 0x7FU, 1}},  {-1}}, /* -1.375000 */
+  {{.ft = {0x100000U, 0x7FU, 0}},  {+1}}, /* 1.125000 */
+  {{.ft = {0x100000U, 0x7FU, 1}},  {-1}}, /* -1.125000 */
+
+  {{.ft = {0x000000U, 0x7FU + 0x16U, 0}},  {+4194304}}, /* 4194304.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x16U, 1}},  {-4194304}}, /* -4194304.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x17U, 0}},  {+8388608}}, /* 8388608.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x17U, 1}},  {-8388608}}, /* -8388608.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x18U, 0}},  {+16777216}}, /* 16777216.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x18U, 1}},  {-16777216}}, /* -16777216.000000 */
+
+  {{.ft = {0x000000U, 0x7FU + 0x1EU, 0}},  {+1073741824}}, /* 1073741824.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x1EU, 1}},  {-1073741824}}, /* -1073741824.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x1FU, 0}},  {+2147483648LL}}, /* 2147483648.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x1FU, 1}},  {-2147483648LL}}, /* -2147483648.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x20U, 0}},  {4294967296}}, /* 4294967296.000000 */
+  {{.ft = {0x000000U, 0x7FU + 0x20U, 1}},  {-4294967296}}, /* -4294967296.000000 */
+
+  /* Different mantissa patterns. */
+  {{.ft = {0x7FFFFFU, 0x96U, 0}},  {+16777215}}, /* 16777215.000000 */
+  {{.ft = {0x7FF000U, 0x95U, 0}},  {+8386560}}, /* 8386560.000000 */
+  {{.ft = {0x1555FFU, 0x8DU, 0}},  {+19115}}, /* 19115.000000 */
+  {{.ft = {0x7FF000U, 0x96U, 1}},  {-16773120}}, /* -16773120.000000 */
+  {{.ft = {0x7FFFFEU, 0x95U, 1}},  {-8388607}}, /* -8388607.000000 */
+  {{.ft = {0x1555FFU, 0x8DU, 1}},  {-19115}}  /* -19115.000000 */
+};
+
+static const size_t n_tests_float = sizeof(tests_float) / sizeof(tests_float[0]);
+
+
+int main(void)
+{
+  unsigned int i, counter;
+
+  for (counter = i = 0; i < n_tests_float; i++)
+  {
+    float result = roundf(tests_float[i].value.f);
+
+    if (tests_float[i].should_be.f == result)
+      counter++;
+    else if ((i >= 10 || i <= 13) && isnan(result))
+      counter++;
+    else
+      printf("roundf test failed:  value to round = %.12f  result = %.12f  should be = %.12f\n", tests_float[i].value.f, result, tests_float[i].should_be.f);
+  }
+  printf("%s\n", (counter < n_tests_float) ? "roundf test failed." : "roundf test succeded.");
+
+  return 0;
+}
diff -aprNU5 djgpp.orig/tests/cygnus/t-roundl.c djgpp/tests/cygnus/t-roundl.c
--- djgpp.orig/tests/cygnus/t-roundl.c    1970-01-01 01:00:00 +0100
+++ djgpp/tests/cygnus/t-roundl.c    2013-10-23 21:58:36 +0100
@@ -0,0 +1,143 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+
+#include <stdio.h>
+#include <math.h>
+#include <libc/ieee.h>
+
+typedef struct {
+  const _longdouble_union_t value;      /* test value */
+  const _longdouble_union_t should_be;  /* result */
+} entry_t;
+
+static const entry_t tests_long_double[] =
+{
+  /* test value */
+  /*     value           should be   */
+
+  /* Zeros. */
+  {{.ldt = {0x0U, 0x0U, 0x0U, 0}},  {0}}, /* 0.0 */
+  {{.ldt = {0x0U, 0x0U, 0x0U, 1}},  {0}}, /* -0.0 */
+
+  /* Subnormals aka denormals. */
+  {{.ldt = {0x1U, 0x0U, 0x0U, 0}},  {0}}, /* Very small number. */
+  {{.ldt = {0x1U, 0x0U, 0x0U, 1}},  {0}}, /* Very small -number. */
+
+  /* Normals. */
+  {{.ldt = {0x0U, 0x80000000U, 0x1U, 0}},  {0}}, /* Small number. */
+  {{.ldt = {0x0U, 0x80000000U, 0x1U, 1}},  {0}}, /* Small -number. */
+  {{.ldt = {0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 0}},  {.ldt = {0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 0}}}, /* Big number. */
+  {{.ldt = {0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 1}},  {.ldt = {0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFEU, 1}}}, /* Big -number. */
+
+  /* Infs. */
+  {{.ldt = {0x0U, 0x80000000U, 0x7FFFU, 0}},  {.ldt = {0x0U, 0x80000000U, 0x7FFFU, 0}}}, /* Inf */
+  {{.ldt = {0x0U, 0x80000000U, 0x7FFFU, 1}},  {.ldt = {0x0U, 0x80000000U, 0x7FFFU, 1}}}, /* -Inf */
+
+  /* NaNs. */
+  {{.ldt = {0x1U, 0x80000000U, 0x7FFFU, 0}},  {.ldt = {0x1U, 0x80000000U, 0x7FFFU, 0}}}, /* SNaN */
+  {{.ldt = {0x1U, 0x80000000U, 0x7FFFU, 1}},  {.ldt = {0x1U, 0x80000000U, 0x7FFFU, 1}}}, /* -SNaN */
+  {{.ldt = {0x0U, 0xFFFFFFFFU, 0x7FFFU, 0}},  {.ldt = {0x0U, 0xFFFFFFFFU, 0x7FFFU, 0}}}, /* QNaN */
+  {{.ldt = {0x0U, 0xFFFFFFFFU, 0x7FFFU, 1}},  {.ldt = {0x0U, 0xFFFFFFFFU, 0x7FFFU, 1}}}, /* -QNaN */
+
+  /* Number. */
+  {{.ldt = {0x2168C000U, 0xC90FDAA2U, 0x3FFFU + 0x0001U, 0}}, {+3}}, /* PI */
+  {{.ldt = {0x2168C000U, 0xC90FDAA2U, 0x3FFFU + 0x0001U, 1}}, {-3}}, /* -PI */
+
+
+  {{.ldt = {0x00000000U, 0xF0000000U, 0x3FFFU + 0x0U, 0}},  {+2}}, /* 1.875000 */
+  {{.ldt = {0x00000000U, 0xF0000000U, 0x3FFFU + 0x0U, 1}},  {-2}}, /* -1.875000 */
+  {{.ldt = {0x00000000U, 0xD0000000U, 0x3FFFU + 0x0U, 0}},  {+2}}, /* 1.625000 */
+  {{.ldt = {0x00000000U, 0xD0000000U, 0x3FFFU + 0x0U, 1}},  {-2}}, /* -1.625000 */
+  {{.ldt = {0xF7A0B800U, 0xC00010C6U, 0x3FFFU + 0x0U, 0}},  {+2}}, /* 1.500002 */
+  {{.ldt = {0xF7A0B800U, 0xC00010C6U, 0x3FFFU + 0x0U, 1}},  {-2}}, /* -1.500002 */
+  {{.ldt = {0x00000000U, 0xC0000000U, 0x3FFFU + 0x0U, 0}},  {+2}}, /* 1.500000 */
+  {{.ldt = {0x00000000U, 0xC0000000U, 0x3FFFU + 0x0U, 1}},  {-2}}, /* -1.500000 */
+  {{.ldt = {0x085F4800U, 0xBFFFEF39U, 0x3FFFU + 0x0U, 0}},  {+1}}, /* 1.499998 */
+  {{.ldt = {0x085F4800U, 0xBFFFEF39U, 0x3FFFU + 0x0U, 1}},  {-1}}, /* -1.499998 */
+  {{.ldt = {0x00000000U, 0xB0000000U, 0x3FFFU + 0x0U, 0}},  {+1}}, /* 1.375000 */
+  {{.ldt = {0x00000000U, 0xB0000000U, 0x3FFFU + 0x0U, 1}},  {-1}}, /* -1.375000 */
+  {{.ldt = {0x00000000U, 0x90000000U, 0x3FFFU + 0x0U, 0}},  {+1}}, /* 1.125000 */
+  {{.ldt = {0x00000000U, 0x90000000U, 0x3FFFU + 0x0U, 1}},  {-1}}, /* -1.125000 */
+
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0016U, 0}}, {+4194304}}, /* 4194304.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0016U, 1}}, {-4194304}}, /* -4194304.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0017U, 0}}, {+8388608}}, /* 8388608.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0017U, 1}}, {-8388608}}, /* -8388608.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0018U, 0}}, {+16777216}}, /* 16777216.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0018U, 1}}, {-16777216}}, /* -16777216.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x001EU, 0}}, {+1073741824}}, /* 1073741824.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x001EU, 1}}, {-1073741824}}, /* -1073741824.000000 */
+  {{.ldt = {0x00000000U, 0xFFFFFFFEU, 0x3FFFU + 0x001EU, 0}}, {+2147483647LL}}, /* 2147483647.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x001FU, 1}}, {-2147483648LL}}, /* -2147483648.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0020U, 0}}, {+4294967296}}, /* 4294967296.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0020U, 1}}, {-4294967296}}, /* -4294967296.000000 */
+
+  {{.ldt = {0x89A00000U, 0x81234567U, 0x3FFFU + 0x0033U, 0}}, {2271815812028928}}, /* 2271815812028928.000000 */
+  {{.ldt = {0x89A00000U, 0x81234567U, 0x3FFFU + 0x0033U, 1}}, {-2271815812028928}}, /* -2271815812028928.000000 */
+  {{.ldt = {0xC4D58000U, 0x8091A2B3U, 0x3FFFU + 0x0034U, 0}}, {4523615625714352}}, /* 4523615625714352.000000 */
+  {{.ldt = {0xC4D58000U, 0x8091A2B3U, 0x3FFFU + 0x0034U, 1}}, {-4523615625714352}}, /* -4523615625714352.000000 */
+  {{.ldt = {0x3B2A1800U, 0xFF6E5D4CU, 0x3FFFU + 0x0034U, 0}}, {8987183256397123}}, /* 8987183256397123.000000 */
+  {{.ldt = {0x3B2A1800U, 0xFF6E5D4CU, 0x3FFFU + 0x0034U, 1}}, {-8987183256397123}}, /* -8987183256397123.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0035U, 0}}, {9007199254740992}}, /* 9007199254740992.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0035U, 1}}, {-9007199254740992}}, /* -9007199254740992.000000 */
+  {{.ldt = {0x4D5E7000U, 0x891A2B3CU, 0x3FFFU + 0x0035U, 0}}, {9647711201744796}}, /* 9647711201744796.000000 */
+  {{.ldt = {0x4D5E7000U, 0x891A2B3CU, 0x3FFFU + 0x0035U, 1}}, {-9647711201744796}}, /* -9647711201744796.000000 */
+  {{.ldt = {0x76543000U, 0xFEDCBA98U, 0x3FFFU + 0x0041U, 0}}, {7.3459034177972256768E19}}, /* 73459034177972256768.000000 */
+  {{.ldt = {0x76543000U, 0xFEDCBA98U, 0x3FFFU + 0x0041U, 1}}, {-7.3459034177972256768E19}}, /* -73459034177972256768.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x003FU, 0}}, {9.223372036854775808E18}}, /* 9223372036854775808.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x003FU, 1}}, {-9.223372036854775808E18}}, /* -9223372036854775808.000000 */
+  {{.ldt = {0x00000000U, 0xC0000000U, 0x3FFFU + 0x003FU, 0}}, {1.3835058055282163712E19}}, /* 13835058055282163712.000000 */
+  {{.ldt = {0x00000000U, 0xC0000000U, 0x3FFFU + 0x003FU, 1}}, {-1.3835058055282163712E19}}, /* -13835058055282163712.000000 */
+  {{.ldt = {0x00000000U, 0xF0000000U, 0x3FFFU + 0x0042U, 0}}, {1.38350580552821637120E20}}, /* 138350580552821637120.000000 */
+  {{.ldt = {0x00000000U, 0xF0000000U, 0x3FFFU + 0x0042U, 1}}, {-1.38350580552821637120E20}}, /* -138350580552821637120.000000 */
+  {{.ldt = {0xBA987800U, 0xF7FFFEDCU, 0x3FFFU + 0x0042U, 0}}, {1.42962256563249856512E20}}, /* 142962256563249856512.000000 */
+  {{.ldt = {0xBA987800U, 0xF7FFFEDCU, 0x3FFFU + 0x0042U, 1}}, {-1.42962256563249856512E20}}, /* -142962256563249856512.000000 */
+  {{.ldt = {0x00000000U, 0xF8000000U, 0x3FFFU + 0x0042U, 0}}, {1.42962266571249025024E20}}, /* 142962266571249025024.000000 */
+  {{.ldt = {0x00000000U, 0xF8000000U, 0x3FFFU + 0x0042U, 1}}, {-1.42962266571249025024E20}}, /* -142962266571249025024.000000 */
+  {{.ldt = {0x00012000U, 0xF8000000U, 0x3FFFU + 0x0042U, 0}}, {1.42962266571249614848E20}}, /* 142962266571249614848.000000 */
+  {{.ldt = {0x00012000U, 0xF8000000U, 0x3FFFU + 0x0042U, 1}}, {-1.42962266571249614848E20}}, /* -142962266571249614848.000000 */
+  {{.ldt = {0x76543000U, 0xFEDCBA98U, 0x3FFFU + 0x0042U, 0}}, {1.46918068355944513536E20}}, /* 146918068355944513536.000000 */
+  {{.ldt = {0x76543000U, 0xFEDCBA98U, 0x3FFFU + 0x0042U, 1}}, {-1.46918068355944513536E20}}, /* 147573952589676396544.000000 */
+  {{.ldt = {0xFFFFF800U, 0xFFFFFFFFU, 0x3FFFU + 0x0042U, 0}}, {1.47573952589676396544E20}}, /* -147573952589676396544.000000 */
+  {{.ldt = {0xFFFFF800U, 0xFFFFFFFFU, 0x3FFFU + 0x0042U, 1}}, {-1.47573952589676396544E20}}, /* -147573952589676396544.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0040U, 0}}, {1.8446744073709551616E19}}, /* 18446744073709551616.000000 */
+  {{.ldt = {0x00000000U, 0x80000000U, 0x3FFFU + 0x0040U, 1}}, {-1.8446744073709551616E19}},  /* -18446744073709551616.000000 */
+
+  /* Number. */
+  {{.ldt = {0x80000F0CU, 0xFFFFFFFFU, 0x3FFFU + 0x001FU, 0}}, {+4294967296}}, /* 4294967295.500001 */
+  {{.ldt = {0x8FFFFF00U, 0xFFFFFFFEU, 0x3FFFU + 0x001FU, 0}}, {+4294967295UL}}, /* 4294967294.562500 */
+  {{.ldt = {0x8000AA00U, 0xFFFFFFFEU, 0x3FFFU + 0x001FU, 0}}, {+4294967295UL}}, /* 4294967294.500010 */
+  {{.ldt = {0x707CD001U, 0xFFFFFFFEU, 0x3FFFU + 0x001FU, 0}}, {+4294967294UL}}, /* 4294967294.439404 */
+  {{.ldt = {0x7FFEB00DU, 0xFFFFFFFEU, 0x3FFFU + 0x001FU, 0}}, {+4294967294UL}}, /* 4294967294.499980 */
+  {{.ldt = {0x90123007U, 0xFFFFFFFFU, 0x3FFFU + 0x001FU, 0}}, {+4294967296}}, /* 4294967295.562778 */
+
+  {{.ldt = {0x0000FFFFU, 0xFFFFFFFFU, 0x3FFFU + 0x003EU, 0}}, {+9223372034707324928}}, /* 9223372034707324927.500000 */
+  {{.ldt = {0x7777777FU, 0xFFFFFFFEU, 0x3FFFU + 0x003EU, 0}}, {+9223372033561967552}}, /* 9223372033561967551.500000 */
+  {{.ldt = {0x9EEEEEE0U, 0xFFFFFFFEU, 0x3FFFU + 0x003EU, 0}}, {+9223372033893037936}}, /* 9223372033893037936.000000 */
+  {{.ldt = {0xEEEEEE07U, 0xFFFFFFFEU, 0x3FFFU + 0x003EU, 0}}, {+9223372034564126468}}, /* 9223372034564126467.500000 */
+  {{.ldt = {0xEEEEEE0EU, 0xFFFFFFFEU, 0x3FFFU + 0x003EU, 0}}, {+9223372034564126471}}, /* 9223372034564126471.000000 */
+  {{.ldt = {0xFFFFFF0FU, 0xFFFFFFFFU, 0x3FFFU + 0x003EU, 0}}, {+9223372036854775688}} /* 9223372036854775687.500000 */
+};
+
+static const size_t n_tests_long_double = sizeof(tests_long_double) / sizeof(tests_long_double[0]);
+
+
+int main(void)
+{
+  unsigned int i, counter;
+
+  for (counter = i = 0; i < n_tests_long_double; i++)
+  {
+    long double result = roundl(tests_long_double[i].value.ld);
+
+    if (tests_long_double[i].should_be.ld == result)
+      counter++;
+    else if ((i >= 10 || i <= 13) && isnan(result))
+      counter++;
+    else
+      printf("roundl test failed:  value to roundl = %.12Lf  result = %.12Lf  should be = %.12Lf\n", tests_long_double[i].value.ld, result, tests_long_double[i].should_be.ld);
+  }
+  printf("%s\n", (counter < n_tests_long_double) ? "roundl test failed." : "roundl test succeded.");
+
+  return 0;
+}

- Raw text -


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