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 -