delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2013/02/23/20:04:23

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX18uPygPr7YuB7ac+aQAO6te6UJdz4ma8XhCFfPPl+
HnsX0+HcsOTdOJ
Message-ID: <51296597.3060304@gmx.de>
Date: Sun, 24 Feb 2013 01:57:59 +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: Implementation of trunc[fl] family of functions.
X-Y-GMX-Trusted: 0
Reply-To: djgpp-workers AT delorie DOT com

Below a patch that implements the trunc[fl] family of functions. The files
have been placed /djgpp/src/libc/c99/math so they become part of libc.a.
May be it is preferred that the functions go into libm.a.  If this is 
preferred,
let me know.  For every supplied function there is a test file and a 
.txh file.
As usual, suggestions, object comments are welcome.

Regards,
Juan M. Guerrero




2013-02-23  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>

     * djgpp/src/libc/c99/math/truncl.c: Implementation of truncl function.

     * djgpp/src/libc/c99/math/truncl.txh: Documentation about truncl 
function.

     * djgpp/tests/libc/c99/math/t-truncl.c: Test truncl function.


2013-02-20  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>

     * djgpp/tests/libc/c99/math/t-trunc.c: Test trunc function.


2013-02-18  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>

     * djgpp/src/libc/c99/math/trunc.c: Implementation of trunc function.

     * djgpp/src/libc/c99/math/trunc.txh: Documentation about trunc 
function.


2013-02-17  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>

     * djgpp/include/math.h: Added trunc[fl] function prototypes.

     * djgpp/src/libc/c99/math/makefile: Added trunc[fl] functions.

     * djgpp/src/libc/c99/math/truncf.c: Implementation of truncf function.

     * djgpp/src/libc/c99/math/truncf.txh: Documentation about truncf 
function.

     * djgpp/src/docs/kb/wc204.txi: Info about trunc[fl] functions added.

     * djgpp/tests/libc/c99/math/makefile: Added t-trunc[fl] functions.

     * djgpp/tests/libc/c99/math/t-truncf.c: Test truncf function.





diff -aprNU5 djgpp.orig/include/math.h djgpp/include/math.h
--- djgpp.orig/include/math.h    2013-02-24 01:12:36 +0000
+++ djgpp/include/math.h    2013-02-24 01:30:14 +0000
@@ -145,10 +145,13 @@ double        cbrt(double _x);
  double        exp2(double _x);
  double        expm1(double _x);
  double        hypot(double _x, double _y);
  double        log1p(double _x);
  double        log2(double _x);
+double        trunc(double _x);
+float         truncf(float _x);
+long double   truncl(long double _x);

  /* These are in libm.a (Cygnus).  You must link -lm to get these */
  /* See libm/math.h for comments */

  extern double erf(double);
diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi    2013-01-27 23:26:04 +0000
+++ djgpp/src/docs/kb/wc204.txi    2013-02-24 01:36:00 +0000
@@ -1272,5 +1272,11 @@ by @code{_doscan} and the @code{scanf} f
  @tindex rlim_t
  @tindex struct rlimit AT r{, and }rlim_t
  The type @code{rlim_t} has been added.
  @code{rlim_t} is now used for the @code{rlim_cur} and @code{rlim_max}
  members of @code{struct rlimit}.
+
+@findex trunc AT r{, added}
+@findex truncf AT r{, added}
+@findex truncl AT r{, added}
+The @acronym{C99} functions @code{trunc}, @code{truncf} and @code{truncl}
+were added.
diff -aprNU5 djgpp.orig/src/libc/c99/math/makefile 
djgpp/src/libc/c99/math/makefile
--- djgpp.orig/src/libc/c99/math/makefile    2008-04-06 21:06:40 +0000
+++ djgpp/src/libc/c99/math/makefile    2013-02-24 01:36:00 +0000
@@ -1,5 +1,6 @@
+# Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details
  # Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details
  # Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details
  TOP=../..

  SRC += errhandl.c
@@ -13,10 +14,13 @@ SRC += fpclassf.S
  SRC += fpclassd.S
  SRC += fpclassl.S
  SRC += sgnbitd.c
  SRC += sgnbitf.c
  SRC += sgnbitld.c
+SRC += trunc.c
+SRC += truncf.c
+SRC += truncl.c

  include $(TOP)/../makefile.inc

  fpclassf.S: fp-asm.h

diff -aprNU5 djgpp.orig/src/libc/c99/math/trunc.c 
djgpp/src/libc/c99/math/trunc.c
--- djgpp.orig/src/libc/c99/math/trunc.c    1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/trunc.c    2013-02-24 01:36:00 +0000
@@ -0,0 +1,62 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+#include <math.h>
+#include <libc/ieee.h>
+
+#define DOUBLE_BIAS                      (0x3FFU)
+#define MAX_BIN_EXPONENT                 (1023)
+#define MIN_BIN_EXPONENT                 (-1022)
+#define BIN_DIGITS_IN_FRACTION           (51)  /*  Amount of binary 
digits in fraction part of mantissa.  */
+#define BIN_DIGITS_IN_MSW                (20)  /*  Amount of binary 
digits in msw of the fraction part of mantissa.  */
+#define NO_SIGNIFICANT_DIGITS_IN_LSW(x)  ((x) < BIN_DIGITS_IN_MSW)
+
+
+double
+trunc(double x)
+{
+  _double_union_t ieee_value;
+  int unbiased_exponent;
+
+
+  ieee_value.d = x;
+  unbiased_exponent = ieee_value.dt.exponent - DOUBLE_BIAS;
+
+  if (NO_SIGNIFICANT_DIGITS_IN_LSW(unbiased_exponent))
+  {
+    /* All significant digits are in msw. */
+    if (unbiased_exponent < 0)
+    {
+      /* The magnitude of the number is < 1 so the result is +-0.  */
+      int sign = ieee_value.dt.sign;
+      ieee_value.d = 0;
+      ieee_value.dt.sign = sign;
+    }
+    else
+    {
+      ieee_value.dt.mantissah &= ~(0x000FFFFFU >> unbiased_exponent);
+      ieee_value.dt.mantissal = 0;
+    }
+
+    return ieee_value.d;
+  }
+  else if (unbiased_exponent > BIN_DIGITS_IN_FRACTION)
+  {
+    if (unbiased_exponent > MAX_BIN_EXPONENT)
+      return x + x;  /* x is NaN or infinite.  */
+  }
+  else
+  {
+    /*
+     *  All fraction bits in msw are relevant.
+     *  Truncate irrelevant bits from lsw.
+     */
+    ieee_value.dt.mantissal &= ~(0xFFFFFFFFU >> (unbiased_exponent - 
BIN_DIGITS_IN_MSW));
+    return ieee_value.d;
+  }
+
+
+  /*
+   *  All bits in the fraction fields of the msw
+   *  and lsw are needed in the result.
+   */
+  return x;
+}
diff -aprNU5 djgpp.orig/src/libc/c99/math/trunc.txh 
djgpp/src/libc/c99/math/trunc.txh
--- djgpp.orig/src/libc/c99/math/trunc.txh    1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/trunc.txh    2013-02-24 01:36:00 +0000
@@ -0,0 +1,32 @@
+@node trunc, math
+@findex trunc
+@subheading Syntax
+
+@example
+#include <math.h>
+
+double trunc(double x);
+@end example
+
+@subheading Description
+
+The function rounds its argument to the integer value, in floating point
+format, nearest to but no larger in magnitude than the argument.
+
+
+@subheading Return Value
+
+The truncated integer value in double format.
+If @var{x} is NaN, a NaN will be returned.
+If @var{x} is +/-0 or +/-Inf, @var{x} will be returned.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+double pi = -3.1415926535897932384626433832795;
+double integer_part = trunc(pi);  /*  Returns -3.0  */
+@end example
diff -aprNU5 djgpp.orig/src/libc/c99/math/truncf.c 
djgpp/src/libc/c99/math/truncf.c
--- djgpp.orig/src/libc/c99/math/truncf.c    1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/truncf.c    2013-02-24 01:36:00 +0000
@@ -0,0 +1,40 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+#include <math.h>
+#include <libc/ieee.h>
+
+#define FLOAT_BIAS              (0x7FU)
+#define MAX_BIN_EXPONENT        (127)
+#define MIN_BIN_EXPONENT        (-126)
+#define BIN_DIGITS_IN_FRACTION  (23)    /*  Amount of binary digits in 
fraction part of mantissa.  */
+
+
+float
+truncf(float x)
+{
+  _float_union_t ieee_value;
+  int unbiased_exponent;
+
+
+  ieee_value.f = x;
+  unbiased_exponent = ieee_value.ft.exponent - FLOAT_BIAS;
+
+  if (unbiased_exponent < BIN_DIGITS_IN_FRACTION)
+  {
+    if (unbiased_exponent < 0)
+    {
+      int sign = ieee_value.ft.sign;
+      ieee_value.f = 0;  /* The magnitude of the number is < 1 so the 
result is +-0.  */
+      ieee_value.ft.sign = sign;
+    }
+    else
+      ieee_value.ft.mantissa &= ~(0x7FFFFFU >> unbiased_exponent);
+
+    return ieee_value.f;
+  }
+  else if (unbiased_exponent > MAX_BIN_EXPONENT)
+    return x + x;    /* x is NaN or infinite.  */
+
+
+  /* All bits in the fraction field are relevant. */
+  return x;
+}
diff -aprNU5 djgpp.orig/src/libc/c99/math/truncf.txh 
djgpp/src/libc/c99/math/truncf.txh
--- djgpp.orig/src/libc/c99/math/truncf.txh    1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/truncf.txh    2013-02-24 01:36:00 +0000
@@ -0,0 +1,32 @@
+@node truncf, math
+@findex truncf
+@subheading Syntax
+
+@example
+#include <math.h>
+
+float truncf(float x);
+@end example
+
+@subheading Description
+
+The function rounds its argument to the integer value, in floating point
+format, nearest to but no larger in magnitude than the argument.
+
+
+@subheading Return Value
+
+The truncated integer value in floating format.
+If @var{x} is NaN, a NaN will be returned.
+If @var{x} is +/-0 or +/-Inf, @var{x} will be returned.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+float pi = -3.1415926535897932384626433832795;
+float integer_part = truncf(pi);  /*  Returns -3.0  */
+@end example
diff -aprNU5 djgpp.orig/src/libc/c99/math/truncl.c 
djgpp/src/libc/c99/math/truncl.c
--- djgpp.orig/src/libc/c99/math/truncl.c    1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/truncl.c    2013-02-24 01:36:00 +0000
@@ -0,0 +1,62 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+#include <math.h>
+#include <libc/ieee.h>
+
+#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_MSW                (31)  /*  Amount of binary 
digits in msw of the fraction part of mantissa.  */
+#define NO_SIGNIFICANT_DIGITS_IN_LSW(x)  ((x) < BIN_DIGITS_IN_MSW)
+
+
+long double
+truncl(long double x)
+{
+  _longdouble_union_t ieee_value;
+  int unbiased_exponent;
+
+
+  ieee_value.ld = x;
+  unbiased_exponent = ieee_value.ldt.exponent - LONG_DOUBLE_BIAS;
+
+  if (NO_SIGNIFICANT_DIGITS_IN_LSW(unbiased_exponent))
+  {
+    /* All significant digits are in msw. */
+    if (unbiased_exponent < 0)
+    {
+      /* The magnitude of the number is < 1 so the result is +-0.  */
+      int sign = ieee_value.ldt.sign;
+      ieee_value.ld = 0;
+      ieee_value.ldt.sign = sign;
+    }
+    else
+    {
+      ieee_value.ldt.mantissah &= ~(0x7FFFFFFFU >> unbiased_exponent);
+      ieee_value.ldt.mantissal = 0;
+    }
+
+    return ieee_value.ld;
+  }
+  else if (unbiased_exponent > BIN_DIGITS_IN_FRACTION)
+  {
+    if (unbiased_exponent > MAX_BIN_EXPONENT)
+      return x + x;  /* x is NaN or infinite.  */
+  }
+  else
+  {
+    /*
+     *  All fraction bits in msw are relevant.
+     *  Truncate irrelevant bits from lsw.
+     */
+    ieee_value.ldt.mantissal &= ~(0xFFFFFFFFU >> (unbiased_exponent - 
BIN_DIGITS_IN_MSW));
+    return ieee_value.ld;
+  }
+
+
+  /*
+   *  All bits in the fraction fields of the msw
+   *  and lsw are needed in the result.
+   */
+  return x;
+}
diff -aprNU5 djgpp.orig/src/libc/c99/math/truncl.txh 
djgpp/src/libc/c99/math/truncl.txh
--- djgpp.orig/src/libc/c99/math/truncl.txh    1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/truncl.txh    2013-02-24 01:36:00 +0000
@@ -0,0 +1,25 @@
+@node truncl, math
+@findex truncl
+@subheading Syntax
+
+@example
+#include <math.h>
+
+long double truncl(long double x);
+@end example
+
+@subheading Description
+
+The function rounds its argument to the integer value, in floating point
+format, nearest to but no larger in magnitude than the argument.
+
+
+@subheading Return Value
+
+The truncated integer value in long double format.
+If @var{x} is NaN, a NaN will be returned.
+If @var{x} is +/-0 or +/-Inf, @var{x} will be returned.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
diff -aprNU5 djgpp.orig/tests/libc/c99/math/makefile 
djgpp/tests/libc/c99/math/makefile
--- djgpp.orig/tests/libc/c99/math/makefile    2003-10-25 11:22:52 +0000
+++ djgpp/tests/libc/c99/math/makefile    2013-02-24 01:36:00 +0000
@@ -1,7 +1,10 @@
  TOP=../..

  SRC += t-fpclas.c
  SRC += t-nan.c
  SRC += t-nan2.c
+SRC += t-trunc.c
+SRC += t-truncf.c
+SRC += t-truncl.c

  include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/tests/libc/c99/math/t-trunc.c 
djgpp/tests/libc/c99/math/t-trunc.c
--- djgpp.orig/tests/libc/c99/math/t-trunc.c    1970-01-01 00:00:00 +0000
+++ djgpp/tests/libc/c99/math/t-trunc.c    2013-02-24 01:36:00 +0000
@@ -0,0 +1,80 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+#include <stdio.h>
+#include <math.h>
+#include <libc/ieee.h>
+
+static const double_t tests_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. */
+  { { 0x1U, 0x0U, 0x1U, 0 }, { 0x0U, 0x0U, 0x0U, 0 } }, /* Small number. */
+  { { 0x1U, 0x0U, 0x1U, 1 }, { 0x0U, 0x0U, 0x0U, 1 } }, /* Small 
-number. */
+  { { 0xFFFFFFFFU, 0x7FFFFU, 0x7FEU, 0 }, { 0xFFFFFFFFU, 0x7FFFFU, 
0x7FEU, 0 } }, /* Big number. */
+  { { 0xFFFFFFFFU, 0x7FFFFU, 0x7FEU, 1 }, { 0xFFFFFFFFU, 0x7FFFFU, 
0x7FEU, 1 } }, /* Big -number. */
+
+  /* Infs. */
+  { { 0x0U, 0x0U, 0x7FFU, 0 }, { 0x0U, 0x0U, 0x7FFU, 0 } }, /* Inf */
+  { { 0x0U, 0x0U, 0x7FFU, 1 }, { 0x0U, 0x0U, 0x7FFU, 1 } }, /* -Inf */
+
+  /* NaNs. */
+  { { 0x1U, 0x0U, 0x7FFU, 0 }, { 0x1U, 0x80000U, 0x7FFU, 0 } }, /* SNaN */
+  { { 0x1U, 0x0U, 0x7FFU, 1 }, { 0x1U, 0x80000U, 0x7FFU, 1 } }, /* -SNaN */
+  { { 0x0U, 0xFFFFFU, 0x7FFU, 0 }, { 0x0U, 0xFFFFFU, 0x7FFU, 0 } }, /* 
QNaN */
+  { { 0x0U, 0xFFFFFU, 0x7FFU, 1 }, { 0x0U, 0xFFFFFU, 0x7FFU, 1 } }, /* 
-QNaN */
+
+  /* Number. */
+  { { 0x54442D18U, 0x921FBU, 0x400U, 0 }, { 0x0U, 0x80000U, 0x400U, 0 } 
}, /* PI */
+  { { 0x54442D18U, 0x921FBU, 0x400U, 1 }, { 0x0U, 0x80000U, 0x400U, 1 } 
}, /* -PI */
+
+  /* Different mantissa patterns. */
+  { { 0xFFFFFFFFU, 0xF0003U, 0x3FFU + 0x016U, 0 }, { 0xC0000000U, 
0xF0003U, 0x415U, 0 } },
+  { { 0xFFFFFFFFU, 0xF0003U, 0x3FFU + 0x015U, 0 }, { 0x80000000U, 
0xF0003U, 0x414U, 0 } },
+  { { 0xFFFFFFFFU, 0xF0003U, 0x3FFU + 0x014U, 0 }, { 0x00000000U, 
0xF0003U, 0x413U, 0 } },
+  { { 0xFFFFFFFFU, 0xF0003U, 0x3FFU + 0x013U, 0 }, { 0x00000000U, 
0xF0002U, 0x412U, 0 } }
+};
+
+static const size_t n_tests_double = sizeof(tests_double) / 
sizeof(tests_double[0]);
+
+
+
+int main(void)
+{
+  int i, counter;
+
+  for (counter = i = 0; i < n_tests_double; i++)
+  {
+    _double_union_t value, result, should_be;
+    value.dt = tests_double[i][0];
+    result.d = trunc(value.d);
+    should_be.dt = tests_double[i][1];
+
+    if (should_be.dt.sign == result.dt.sign &&
+        should_be.dt.exponent == result.dt.exponent &&
+        should_be.dt.mantissah == result.dt.mantissah &&
+        should_be.dt.mantissal == result.dt.mantissal)
+    {
+      result.d = trunc(value.d);
+      if (should_be.dt.sign == result.dt.sign &&
+          should_be.dt.exponent == result.dt.exponent &&
+          should_be.dt.mantissah == result.dt.mantissah &&
+          should_be.dt.mantissal == result.dt.mantissal)
+        counter++;
+      else
+        printf("Test failed:  value to truncate = %.12lg  result = 
%.12lg  should be = %.12lg\n", value.d, result.d, should_be.d);
+    }
+    else
+      printf("Test failed:  value to truncate = %.12lg  result = 
%.12lg  should be = %.12lg\n", value.d, result.d, should_be.d);
+  }
+  printf("%s\n", (counter < n_tests_double) ? "Test failed." : "Test 
succeded.");
+
+  return 0;
+}
diff -aprNU5 djgpp.orig/tests/libc/c99/math/t-truncf.c 
djgpp/tests/libc/c99/math/t-truncf.c
--- djgpp.orig/tests/libc/c99/math/t-truncf.c    1970-01-01 00:00:00 +0000
+++ djgpp/tests/libc/c99/math/t-truncf.c    2013-02-24 01:36:00 +0000
@@ -0,0 +1,76 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+#include <stdio.h>
+#include <math.h>
+#include <libc/ieee.h>
+
+static const float_t tests_float[][2] =
+{
+  /*    value             should be        */
+  /* Zeros. */
+  { { 0x0U, 0x0U, 0 }, { 0x0U, 0x0U, 0 } }, /* 0.0 */
+  { { 0x0U, 0x0U, 1 }, { 0x0U, 0x0U, 1 } }, /* -0.0 */
+
+  /* Subnormals aka denormals. */
+  { { 0x1U, 0x0U, 0 }, { 0x0U, 0x0U, 0 } }, /* Very small number. */
+  { { 0x1U, 0x0U, 1 }, { 0x0U, 0x0U, 1 } }, /* Very small -number. */
+
+  /* Normals. */
+  { { 0x1U, 0x1U, 0 }, { 0x0U, 0x0U, 0 } }, /* Small number. */
+  { { 0x1U, 0x1U, 1 }, { 0x0U, 0x0U, 1 } }, /* Small -number. */
+  { { 0xFFFFU, 0xFEU, 0 }, { 0xFFFFU, 0xFEU, 0 } }, /* Big number. */
+  { { 0xFFFFU, 0xFEU, 1 }, { 0xFFFFU, 0xFEU, 1 } }, /* Big -number. */
+
+  /* Infs. */
+  { { 0x0U, 0xFFU, 0 }, { 0x0U, 0xFFU, 0 } }, /* Inf */
+  { { 0x0U, 0xFFU, 1 }, { 0x0U, 0xFFU, 1 } }, /* -Inf */
+
+  /* NaNs. */
+  { { 0x1U, 0xFFU, 0 }, { 0x400001U, 0xFFU, 0 } }, /* SNaN */
+  { { 0x1U, 0xFFU, 1 }, { 0x400001U, 0xFFU, 1 } }, /* -SNaN */
+  { { 0x7FFFFFU, 0xFFU, 0 }, { 0x7FFFFFU, 0xFFU, 0 } }, /* QNaN */
+  { { 0x7FFFFFU, 0xFFU, 1 }, { 0x7FFFFFU, 0xFFU, 1 } }, /* -QNaN */
+
+  /* Number. */
+  { { 0x490FDBU, 0x80U, 0 }, { 0x400000U, 0x80U, 0 } }, /* PI */
+  { { 0x490FDBU, 0x80U, 1 }, { 0x400000U, 0x80U, 1 } }, /* -PI */
+
+  /* Different mantissa patterns. */
+  { { 0x7FFFFFU, 0x96U, 0 }, { 0x7FFFFFU, 0x96U, 0 } },
+  { { 0x7FFFFFU, 0x95U, 0 }, { 0x7FFFFEU, 0x95U, 0 } },
+  { { 0x1555FFU, 0x8DU, 0 }, { 0x155400U, 0x8DU, 0 } }
+};
+
+static const size_t n_tests_float = sizeof(tests_float) / 
sizeof(tests_float[0]);
+
+
+int main(void)
+{
+  int i, counter;
+
+  for (counter = i = 0; i < n_tests_float; i++)
+  {
+    _float_union_t value, result, should_be;
+    value.ft = tests_float[i][0];
+    result.f = truncf(value.f);
+    should_be.ft = tests_float[i][1];
+
+    if (should_be.ft.sign == result.ft.sign &&
+        should_be.ft.exponent == result.ft.exponent &&
+        should_be.ft.mantissa == result.ft.mantissa)
+    {
+      result.f = truncf(result.f);
+      if (should_be.ft.sign == result.ft.sign &&
+          should_be.ft.exponent == result.ft.exponent &&
+          should_be.ft.mantissa == result.ft.mantissa)
+        counter++;
+      else
+        printf("Test failed:  value to truncate = %.5g  result = %.5g  
should be = %.5g\n", value.f, result.f, should_be.f);
+    }
+    else
+      printf("Test failed:  value to truncate = %.5g  result = %.5g  
should be = %.5g\n", value.f, result.f, should_be.f);
+  }
+  printf("%s\n", (counter < n_tests_float) ? "Test failed." : "Test 
succeded.");
+
+  return 0;
+}
diff -aprNU5 djgpp.orig/tests/libc/c99/math/t-truncl.c 
djgpp/tests/libc/c99/math/t-truncl.c
--- djgpp.orig/tests/libc/c99/math/t-truncl.c    1970-01-01 00:00:00 +0000
+++ djgpp/tests/libc/c99/math/t-truncl.c    2013-02-24 01:36:00 +0000
@@ -0,0 +1,80 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+#include <stdio.h>
+#include <math.h>
+#include <libc/ieee.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 }, { 0xC0000000U, 
0xF0000003U, 0x4020U, 0 } },
+  { { 0xFFFFFFFFU, 0xF0000003U, 0x3FFFU + 0x0020U, 0 }, { 0x80000000U, 
0xF0000003U, 0x401FU, 0 } },
+  { { 0xFFFFFFFFU, 0xF0000003U, 0x3FFFU + 0x001FU, 0 }, { 0x00000000U, 
0xF0000003U, 0x401EU, 0 } },
+  { { 0xFFFFFFFFU, 0xF0000003U, 0x3FFFU + 0x001EU, 0 }, { 0x00000000U, 
0xF0000002U, 0x401DU, 0 } }
+};
+
+static const size_t n_tests_long_double = sizeof(tests_long_double) / 
sizeof(tests_long_double[0]);
+
+
+
+int main(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 = truncl(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("Test failed:  value to truncate = %.15Lg  result = 
%.15Lg  should be = %.15Lg\n", value.ld, result.ld, should_be.ld);
+    }
+    else
+      printf("Test failed:  value to truncate = %.15Lg  result = 
%.15Lg  should be = %.15Lg\n", value.ld, result.ld, should_be.ld);
+  }
+  printf("%s\n", (counter < n_tests_long_double) ? "Test failed." : 
"Test succeded.");
+
+  return 0;
+}

- Raw text -


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