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 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. Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit 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 * 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 +#include +#include + +#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 -<>, <>, <>, <>---round and remainder +<>, <>, <>, <>, <>---round and remainder INDEX rint INDEX rintf INDEX + rintl +INDEX remainder INDEX remainderf ANSI_SYNOPSIS #include 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 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 -<> and <> returns their argument rounded to the nearest +<>, <> and <> returns their argument rounded to the nearest integer. <> and <> find the remainder of <[x]>/<[y]>; this value is in the range -<[y]>/2 .. +<[y]>/2. RETURNS <> and <> return the integer result as a double. PORTABILITY -<> and <> are System V release 4. <> and +<> and <> are System V release 4. <>, <> and <> 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; +}