Commit 980d2709 authored by Ben Pfaff's avatar Ben Pfaff

Implement 'round', 'roundf', 'roundl' modules.

parent 36454274
2007-10-20 Ben Pfaff <blp@gnu.org>
* lib/math.in.h: Declare round, roundf, roundl if we are providing
implementations.
* m4/math_h.m4: New substitutions for round, roundf, roundl modules.
* lib/round.c: New file.
* lib/roundf.c: New file.
* lib/roundl.c: New file.
* m4/round.m4: New file.
* m4/roundf.m4: New file.
* m4/roundl.m4: New file.
* m4/check-libm-func-m4: New file.
* modules/math: Replace round, roundf, roundl related @VARS@ in
math.in.h.
* modules/round: New file.
* modules/round-tests: New file.
* modules/roundf: New file.
* modules/roundf-tests: New file.
* modules/roundl: New file.
* modules/roundl-tests: New file.
* tests/test-round1.c: New file.
* tests/test-round2.c: New file.
* tests/test-roundf1.c: New file.
* tests/test-roundf2.c: New file.
* tests/test-roundl.c: New file.
* doc/functions/round.texi: Mention round module.
* doc/functions/roundf.texi: Mention roundf module.
* doc/functions/roundl.texi: Mention roundl module.
* MODULES.html.sh: Mention new modules.
2007-10-20 Jim Meyering <meyering@redhat.com>
* lib/xprintf.c: Include <config.h> unconditionally.
......@@ -1977,6 +1977,9 @@ func_all_modules ()
func_module ldexpl
func_module math
func_module mathl
func_module round
func_module roundf
func_module roundl
func_module signbit
func_module trunc
func_module truncf
......
......@@ -4,15 +4,15 @@
POSIX specification: @url{http://www.opengroup.org/susv3xsh/round.html}
Gnulib module: ---
Gnulib module: round
Portability problems fixed by Gnulib:
@itemize
@item
This function is missing on some platforms:
FreeBSD 5.2.1, OpenBSD 3.8, AIX 5.1, IRIX 6.5, OSF/1 4.0, Solaris 9, Interix 3.5.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@item
This function is missing on some platforms:
FreeBSD 5.2.1, OpenBSD 3.8, AIX 5.1, IRIX 6.5, OSF/1 4.0, Solaris 9, Interix 3.5.
@end itemize
......@@ -4,15 +4,15 @@
POSIX specification: @url{http://www.opengroup.org/susv3xsh/roundf.html}
Gnulib module: ---
Gnulib module: roundf
Portability problems fixed by Gnulib:
@itemize
@item
This function is missing on some platforms:
FreeBSD 5.2.1, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 4.0, Solaris 9, Interix 3.5.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@item
This function is missing on some platforms:
FreeBSD 5.2.1, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 4.0, Solaris 9, Interix 3.5.
@end itemize
......@@ -4,15 +4,15 @@
POSIX specification: @url{http://www.opengroup.org/susv3xsh/roundl.html}
Gnulib module: ---
Gnulib module: roundl
Portability problems fixed by Gnulib:
@itemize
@item
This function is missing on some platforms:
FreeBSD 5.2.1, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 4.0, Solaris 9, Cygwin, Interix 3.5, BeOS.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@item
This function is missing on some platforms:
FreeBSD 5.2.1, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 4.0, Solaris 9, Cygwin, Interix 3.5, BeOS.
@end itemize
......@@ -217,6 +217,48 @@ extern long double logl (long double x);
#endif
#if @GNULIB_ROUNDF@
# if !@HAVE_DECL_ROUNDF@
# define roundf rpl_roundf
extern float roundf (float x);
# endif
#elif defined GNULIB_POSIXCHECK
# undef roundf
# define roundf(x) \
(GL_LINK_WARNING ("roundf is unportable - " \
"use gnulib module roundf for portability"), \
roundf (x))
#endif
#if @GNULIB_ROUND@
# if !@HAVE_DECL_ROUND@
# define round rpl_round
extern double round (double x);
# endif
#elif defined GNULIB_POSIXCHECK
# undef round
# define round(x) \
(GL_LINK_WARNING ("round is unportable - " \
"use gnulib module round for portability"), \
round (x))
#endif
#if @GNULIB_ROUNDL@
# if !@HAVE_DECL_ROUNDL@
# define roundl rpl_roundl
extern long double roundl (long double x);
# endif
#elif defined GNULIB_POSIXCHECK
# undef roundl
# define roundl(x) \
(GL_LINK_WARNING ("roundl is unportable - " \
"use gnulib module roundl for portability"), \
roundl (x))
#endif
#if @GNULIB_MATHL@ || !@HAVE_DECL_SINL@
extern long double sinl (long double x);
#endif
......
/* Round toward nearest, breaking ties away from zero.
Copyright (C) 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Written by Ben Pfaff <blp@gnu.org>, 2007.
Based heavily on code by Bruno Haible. */
#include <config.h>
#include <float.h>
#include <math.h>
#ifdef USE_LONG_DOUBLE
# define ROUND roundl
# define FLOOR floorl
# define CEIL ceill
# define DOUBLE long double
# define MANT_DIG LDBL_MANT_DIG
# define L_(literal) literal##L
# define HAVE_FLOOR_AND_CEIL (HAVE_DECL_FLOORL && HAVE_DECL_CEILL)
#elif ! defined USE_FLOAT
# define ROUND round
# define FLOOR floor
# define CEIL ceil
# define DOUBLE double
# define MANT_DIG DBL_MANT_DIG
# define L_(literal) literal
# define HAVE_FLOOR_AND_CEIL 1
#else /* defined USE_FLOAT */
# define ROUND roundf
# define FLOOR floorf
# define CEIL ceilf
# define DOUBLE float
# define MANT_DIG FLT_MANT_DIG
# define L_(literal) literal##f
# define HAVE_FLOOR_AND_CEIL (HAVE_DECL_FLOORF && HAVE_DECL_CEILF)
#endif
/* If we're being included from test-round2[f].c, it already defined names for
our round implementations. Otherwise, pick the preferred implementation for
this machine. */
#if !defined FLOOR_BASED_ROUND && !defined FLOOR_FREE_ROUND
# if HAVE_FLOOR_AND_CEIL
# define FLOOR_BASED_ROUND ROUND
# else
# define FLOOR_FREE_ROUND ROUND
# endif
#endif
#ifdef FLOOR_BASED_ROUND
/* An implementation of the C99 round function based on floor and ceil. We use
this when floor and ceil are available, on the assumption that they are
faster than the open-coded versions below. */
DOUBLE
FLOOR_BASED_ROUND (DOUBLE x)
{
if (x >= L_(0.0))
{
DOUBLE y = FLOOR (x);
if (x - y >= L_(0.5))
y += L_(1.0);
return y;
}
else
{
DOUBLE y = CEIL (x);
if (y - x >= L_(0.5))
y -= L_(1.0);
return y;
}
}
#endif /* FLOOR_BASED_ROUND */
#ifdef FLOOR_FREE_ROUND
/* An implementation of the C99 round function without floor or ceil.
We use this when floor or ceil is missing. */
DOUBLE
FLOOR_FREE_ROUND (DOUBLE x)
{
/* 2^(MANT_DIG-1). */
static const DOUBLE TWO_MANT_DIG =
/* Assume MANT_DIG <= 5 * 31.
Use the identity
n = floor(n/5) + floor((n+1)/5) + ... + floor((n+4)/5). */
(DOUBLE) (1U << ((MANT_DIG - 1) / 5))
* (DOUBLE) (1U << ((MANT_DIG - 1 + 1) / 5))
* (DOUBLE) (1U << ((MANT_DIG - 1 + 2) / 5))
* (DOUBLE) (1U << ((MANT_DIG - 1 + 3) / 5))
* (DOUBLE) (1U << ((MANT_DIG - 1 + 4) / 5));
/* The use of 'volatile' guarantees that excess precision bits are dropped at
each addition step and before the following comparison at the caller's
site. It is necessary on x86 systems where double-floats are not IEEE
compliant by default, to avoid that the results become platform and
compiler option dependent. 'volatile' is a portable alternative to gcc's
-ffloat-store option. */
volatile DOUBLE y = x;
volatile DOUBLE z = y;
if (z > L_(0.0))
{
/* Avoid rounding error for x = 0.5 - 2^(-MANT_DIG-1). */
if (z < L_(0.5))
z = L_(0.0);
/* Avoid rounding errors for values near 2^k, where k >= MANT_DIG-1. */
else if (z < TWO_MANT_DIG)
{
/* Add 0.5 to the absolute value. */
y = z += L_(0.5);
/* Round to the next integer (nearest or up or down, doesn't
matter). */
z += TWO_MANT_DIG;
z -= TWO_MANT_DIG;
/* Enforce rounding down. */
if (z > y)
z -= L_(1.0);
}
}
else if (z < L_(0.0))
{
/* Avoid rounding error for x = -(0.5 - 2^(-MANT_DIG-1)). */
if (z > - L_(0.5))
z = L_(0.0);
/* Avoid rounding errors for values near -2^k, where k >= MANT_DIG-1. */
else if (z > -TWO_MANT_DIG)
{
/* Add 0.5 to the absolute value. */
y = z -= L_(0.5);
/* Round to the next integer (nearest or up or down, doesn't
matter). */
z -= TWO_MANT_DIG;
z += TWO_MANT_DIG;
/* Enforce rounding up. */
if (z < y)
z += L_(1.0);
}
}
return z;
}
#endif /* FLOOR_FREE_ROUND */
/* Round toward nearest, breaking ties away from zero.
Copyright (C) 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#define USE_FLOAT
#include "round.c"
/* Round toward nearest, breaking ties away from zero.
Copyright (C) 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#define USE_LONG_DOUBLE
#include "round.c"
# check-libm.m4 serial 1
dnl Copyright (C) 2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl AC_CHECK_LIBM_FUNC (MATH_FUNCTION, INVOCATION,
dnl [RUN-IF-FOUND], [RUN-IF-NOT-FOUND])
dnl
dnl Checks for a declaration of the given MATH_FUNCTION in <math.h>, and
dnl substitutes HAVE_DECL_<func> accordingly. If a declaration is found,
dnl determines the needed library (if any), assigns it to <func>_LIBM, and
dnl executes RUN-IF-FOUND; otherwise, executes RUN-IF-NOT-FOUND.
dnl
dnl INVOCATION should be a C statement that invokes MATH_FUNCTION, both
dnl using and assigning back to double variable 'x', e.g. "x = floor
dnl (x);".
AC_DEFUN([gl_CHECK_LIBM_FUNC],
[
m4_pushdef([FUNC_LIBM], m4_toupper([$1])[_LIBM])dnl
m4_pushdef([HAVE_DECL_FUNC], HAVE_DECL_[]m4_toupper([$1]))dnl
AC_CHECK_DECLS([$1], , , [#include <math.h>])
if test "$ac_cv_have_decl_$1" = yes; then
save_LIBS=$LIBS
FUNC_LIBM=?
for libm in "" "-lm"; do
LIBS="$save_LIBS $libm"
AC_TRY_LINK([
#ifndef __NO_MATH_INLINES
# define __NO_MATH_INLINES 1 /* for glibc */
#endif
#include <math.h>
double x;],
[$2],
[FUNC_LIBM=$libm
break])
done
LIBS=$save_LIBS
if test "$FUNC_LIBM" = "?"; then
FUNC_LIBM=
fi
m4_ifvaln([$3], [$3])dnl
else
HAVE_DECL_FUNC=
FUNC_LIBM=
m4_ifvaln([$4], [$4])dnl
fi
AC_SUBST(HAVE_DECL_FUNC)
AC_SUBST(FUNC_LIBM)
m4_popdef([FUNC_LIBM])
m4_popdef([HAVE_DECL_FUNC])])
......@@ -27,6 +27,9 @@ AC_DEFUN([gl_MATH_H_DEFAULTS],
GNULIB_FREXPL=0; AC_SUBST([GNULIB_FREXPL])
GNULIB_LDEXPL=0; AC_SUBST([GNULIB_LDEXPL])
GNULIB_MATHL=0; AC_SUBST([GNULIB_MATHL])
GNULIB_ROUND=0; AC_SUBST([GNULIB_ROUND])
GNULIB_ROUNDF=0; AC_SUBST([GNULIB_ROUNDF])
GNULIB_ROUNDL=0; AC_SUBST([GNULIB_ROUNDL])
GNULIB_SIGNBIT=0; AC_SUBST([GNULIB_SIGNBIT])
GNULIB_TRUNC=0; AC_SUBST([GNULIB_TRUNC])
GNULIB_TRUNCF=0; AC_SUBST([GNULIB_TRUNCF])
......@@ -44,6 +47,9 @@ AC_DEFUN([gl_MATH_H_DEFAULTS],
HAVE_DECL_FREXPL=1; AC_SUBST([HAVE_DECL_FREXPL])
HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL])
HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL])
HAVE_DECL_ROUND=1; AC_SUBST([HAVE_DECL_ROUND])
HAVE_DECL_ROUNDF=1; AC_SUBST([HAVE_DECL_ROUNDF])
HAVE_DECL_ROUNDL=1; AC_SUBST([HAVE_DECL_ROUNDL])
HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL])
HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL])
HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL])
......
# round.m4 serial 1
dnl Copyright (C) 2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_ROUND],
[
AC_REQUIRE([gl_MATH_H_DEFAULTS])
dnl Persuade glibc <math.h> to declare round().
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
gl_CHECK_LIBM_FUNC([round], [x = round(x);], [], [
AC_REQUIRE([gl_FUNC_FLOOR])
ROUND_LIBM=$FLOOR_LIBM
AC_LIBOBJ([round])])])
# roundf.m4 serial 1
dnl Copyright (C) 2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_ROUNDF],
[
AC_REQUIRE([gl_MATH_H_DEFAULTS])
dnl Persuade glibc <math.h> to declare roundf().
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
dnl Test whether roundf() is declared.
gl_CHECK_LIBM_FUNC([roundf], [x = roundf(x);], [], [
dnl No. Are both floorf() and ceilf() available? If so then we can use
dnl them to implement roundf(), on the assumption that they're fast.
gl_CHECK_LIBM_FUNC([floorf], [x = floorf(x);], [
AC_CHECK_DECL([ceilf],
[dnl Yes. Both are declared. Link against the necessary library.
ROUNDF_LIBM="$FLOORF_LIBM"],
[: dnl No. We will use an implementation that doesn't need them.
], [#include <math.h>
])])])])
# roundl.m4 serial 1
dnl Copyright (C) 2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_ROUNDL],
[
AC_REQUIRE([gl_MATH_H_DEFAULTS])
dnl Persuade glibc <math.h> to declare roundl().
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
dnl Test whether roundl() is declared.
gl_CHECK_LIBM_FUNC([roundl], [x = roundl(x);], [], [
dnl No. Are both floorl() and ceill() available? If so then we can use
dnl them to implement roundl(), on the assumption that they're fast.
gl_CHECK_LIBM_FUNC([floorl], [x = floorl(x);], [
AC_CHECK_DECL([ceill],
[dnl Yes. Both are declared. Link against the necessary library.
ROUNDL_LIBM="$FLOORL_LIBM"],
[: dnl No. We will use an implementation that doesn't need them.
], [#include <math.h>
])])])])
......@@ -30,6 +30,9 @@ math.h: math.in.h
-e 's|@''GNULIB_FREXPL''@|$(GNULIB_FREXPL)|g' \
-e 's|@''GNULIB_LDEXPL''@|$(GNULIB_LDEXPL)|g' \
-e 's|@''GNULIB_MATHL''@|$(GNULIB_MATHL)|g' \
-e 's|@''GNULIB_ROUND''@|$(GNULIB_ROUND)|g' \
-e 's|@''GNULIB_ROUNDF''@|$(GNULIB_ROUNDF)|g' \
-e 's|@''GNULIB_ROUNDL''@|$(GNULIB_ROUNDL)|g' \
-e 's|@''GNULIB_SIGNBIT''@|$(GNULIB_SIGNBIT)|g' \
-e 's|@''GNULIB_TRUNC''@|$(GNULIB_TRUNC)|g' \
-e 's|@''GNULIB_TRUNCF''@|$(GNULIB_TRUNCF)|g' \
......@@ -46,6 +49,9 @@ math.h: math.in.h
-e 's|@''HAVE_DECL_FREXPL''@|$(HAVE_DECL_FREXPL)|g' \
-e 's|@''HAVE_DECL_LDEXPL''@|$(HAVE_DECL_LDEXPL)|g' \
-e 's|@''HAVE_DECL_LOGL''@|$(HAVE_DECL_LOGL)|g' \
-e 's|@''HAVE_DECL_ROUND''@|$(HAVE_DECL_ROUND)|g' \
-e 's|@''HAVE_DECL_ROUNDF''@|$(HAVE_DECL_ROUNDF)|g' \
-e 's|@''HAVE_DECL_ROUNDL''@|$(HAVE_DECL_ROUNDL)|g' \
-e 's|@''HAVE_DECL_SINL''@|$(HAVE_DECL_SINL)|g' \
-e 's|@''HAVE_DECL_SQRTL''@|$(HAVE_DECL_SQRTL)|g' \
-e 's|@''HAVE_DECL_TANL''@|$(HAVE_DECL_TANL)|g' \
......
Description:
round() function: round toward nearest, breaking ties away from zero.
Files:
lib/round.c
m4/check-libm-func.m4
m4/round.m4
Depends-on:
float
floor
math
extensions
configure.ac:
gl_FUNC_ROUND
gl_MATH_MODULE_INDICATOR([round])
Makefile.am:
Include:
<math.h>
Link:
$(ROUND_LIBM)
License:
LGPL
Maintainer:
Ben Pfaff
Files:
tests/test-round1.c
tests/test-round2.c
Depends-on:
isnan-nolibm
stdbool
stdint
fprintf-posix
verify
configure.ac:
Makefile.am:
TESTS += test-round1 test-round2
check_PROGRAMS += test-round1 test-round2
test_round1_LDADD = $(LDADD) @ROUND_LIBM@
test_round2_LDADD = $(LDADD) @ROUND_LIBM@
License:
LGPL
Description:
roundf() function: round toward nearest, breaking ties away from zero.
Files:
lib/round.c
lib/roundf.c
m4/check-libm-func.m4
m4/roundf.m4
Depends-on:
float
math
extensions
configure.ac:
gl_FUNC_ROUNDF
gl_MATH_MODULE_INDICATOR([roundf])
Makefile.am:
Include:
<math.h>
Link:
$(ROUNDF_LIBM)
License:
LGPL
Maintainer:
Ben Pfaff
Files:
tests/test-roundf1.c
tests/test-round2.c
tests/test-roundf2.c
Depends-on:
isnanf-nolibm
stdbool
stdint
fprintf-posix
verify
configure.ac:
Makefile.am:
TESTS += test-roundf1 test-roundf2
check_PROGRAMS += test-roundf1 test-roundf2
test_roundf1_LDADD = $(LDADD) @ROUNDF_LIBM@
test_roundf2_LDADD = $(LDADD) @ROUNDF_LIBM@
License:
LGPL
Description:
roundl() function: round toward nearest, breaking ties away from zero.
Files:
lib/round.c
lib/roundl.c
m4/check-libm-func.m4
m4/roundl.m4
Depends-on:
float
math
extensions
configure.ac:
gl_FUNC_ROUNDL
gl_MATH_MODULE_INDICATOR([roundl])
Makefile.am:
Include:
<math.h>
Link:
$(ROUNDL_LIBM)
License:
LGPL
Maintainer:
Ben Pfaff
Files:
tests/test-roundl.c
Depends-on:
fpucw
isnanl-nolibm
configure.ac:
Makefile.am:
TESTS += test-roundl
check_PROGRAMS += test-roundl
test_roundl_LDADD = $(LDADD) @ROUNDL_LIBM@
License:
LGPL
/* Test of rounding to nearest, breaking ties away from zero.
Copyright (C) 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Written by Ben Pfaff <blp@gnu.org>, 2007.
Based heavily on Bruno Haible's test-trunc.c. */
#include <config.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define ASSERT(expr) \
do \
{ \
if (!(expr)) \
{ \
fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
abort (); \
} \
} \
while (0)
/* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0. */
#ifdef __DECC
static double
NaN ()
{
static double zero = 0.0;
return zero / zero;
}
#else
# define NaN() (0.0 / 0.0)
#endif
int
main ()
{
/* Zero. */
ASSERT (round (0.0) == 0.0);
ASSERT (round (-0.0) == 0.0);
/* Positive numbers. */
ASSERT (round (0.3) == 0.0);
ASSERT (round (0.5) == 1.0);
ASSERT (round (0.7) == 1.0);
ASSERT (round (1.0) == 1.0);
ASSERT (round (1.5) == 2.0);
ASSERT (round (2.5) == 3.0);
ASSERT (round (1.999) == 2.0);
ASSERT (round (2.0) == 2.0);
ASSERT (round (65535.999) == 65536.0);
ASSERT (round (65536.0) == 65536.0);
ASSERT (round (65536.001) == 65536.0);
ASSERT (round (2.341e31) == 2.341e31);
/* Negative numbers. */
ASSERT (round (-0.3) == 0.0);
ASSERT (round (-0.5) == -1.0);
ASSERT (round (-0.7) == -1.0);
ASSERT (round (-1.0) == -1.0);
ASSERT (round (-1.5) == -2.0);
ASSERT (round (-2.5) == -3.0);
ASSERT (round (-1.999) == -2.0);
ASSERT (round (-2.0) == -2.0);
ASSERT (round (-65535.999) == -65536.0);
ASSERT (round (-65536.0) == -65536.0);
ASSERT (round (-65536.001) == -65536.0);
ASSERT (round (-2.341e31) == -2.341e31);
/* Infinite numbers. */
ASSERT (round (1.0 / 0.0) == 1.0 / 0.0);
ASSERT (round (-1.0 / 0.0) == -1.0 / 0.0);
/* NaNs. */
ASSERT (isnan (round (NaN ())));
return 0;
}
/* Test of rounding to nearest, breaking ties away from zero.
Copyright (C) 2007 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */