# HG changeset patch # User Bruno Haible # Date 1156769660 0 # Node ID 4e6b2be7a1292cf209b832e8f77e1837268443dc # Parent 47e98e70a47d1e3af4852ca6b72e01ec66e68dd7 New module 'imaxdiv'. diff --git a/lib/imaxdiv.c b/lib/imaxdiv.c new file mode 100644 --- /dev/null +++ b/lib/imaxdiv.c @@ -0,0 +1,66 @@ +/* imaxdiv() function: division of 'intmax_t'. + Copyright (C) 2006 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. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include + +#include + +imaxdiv_t +imaxdiv (intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + /* Verify the requirements of ISO C 99 section 6.5.5 paragraph 6: + "When integers are divided, the result of the / operator is the + algebraic quotient with any fractional part discarded. (This is + often called "truncation toward zero".) If the quotient a/b is + representable, the expression (a/b)*b + a%b shall equal a." */ + if (!(denom == 0 + || (INTMAX_MIN + INTMAX_MAX < 0 + && denom == -1 + && numer < - INTMAX_MAX))) + { + if (!(result.quot * denom + result.rem == numer)) + /* The compiler's implementation of / and % is broken. */ + abort (); + if (!(numer >= 0 + ? result.rem >= 0 + && (denom >= 0 + ? result.rem < denom + : /* Don't write result.rem < - denom, + as it gives integer overflow if denom == INTMAX_MIN. */ + - result.rem > denom) + : result.rem <= 0 + && (denom >= 0 + ? result.rem > - denom + : result.rem > denom))) + /* The compiler's implementation of / and % may be ok according to + C89, but not to C99. Please report this to . + This might be a big portability problem. */ + abort (); + } + + return result; +} diff --git a/m4/imaxdiv.m4 b/m4/imaxdiv.m4 new file mode 100644 --- /dev/null +++ b/m4/imaxdiv.m4 @@ -0,0 +1,17 @@ +# imaxdiv.m4 serial 1 +dnl Copyright (C) 2006 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_IMAXDIV], +[ + AC_REQUIRE([gl_INTTYPES_H]) + if test "$ac_cv_have_decl_imaxdiv" != yes; then + AC_LIBOBJ([imaxdiv]) + gl_PREREQ_IMAXDIV + fi +]) + +# Prerequisites of lib/imaxdiv.c. +AC_DEFUN([gl_PREREQ_IMAXDIV], [:]) diff --git a/modules/imaxdiv b/modules/imaxdiv new file mode 100644 --- /dev/null +++ b/modules/imaxdiv @@ -0,0 +1,23 @@ +Description: +imaxdiv() function: division of 'intmax_t'. + +Files: +lib/imaxdiv.c +m4/imaxdiv.m4 + +Depends-on: +inttypes + +configure.ac: +gl_FUNC_IMAXDIV + +Makefile.am: + +Include: + + +License: +LGPL + +Maintainer: +Bruno Haible