diff options
author | Roland McGrath <roland@gnu.org> | 1992-09-11 00:24:12 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1992-09-11 00:24:12 +0000 |
commit | 49c431d3c72544b79e71bac67bd9cb79ed34896b (patch) | |
tree | 41c3a7159fdf6e24373f42639f65995547f795fc /stdlib | |
parent | 35d45a64aba9f9b1ee7eb866a8ac183f36cbce37 (diff) |
entered into RCS
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/div.c | 69 | ||||
-rw-r--r-- | stdlib/ldiv.c | 67 |
2 files changed, 121 insertions, 15 deletions
diff --git a/stdlib/div.c b/stdlib/div.c index 64e634c11b..5a0ee7da38 100644 --- a/stdlib/div.c +++ b/stdlib/div.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. +/* Copyright (C) 1992 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,6 +16,42 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + #include <ansidecl.h> #include <stdlib.h> @@ -26,14 +62,31 @@ div_t DEFUN(div, (numer, denom), int numer AND int denom) { div_t result; - /* Behavior for negative numbers is guaranteed. */ - register int sign = (numer < 0) == (denom < 0) ? 1 : -1; - numer = numer < 0 ? -numer : numer; - denom = denom < 0 ? -denom : denom; + result.quot = numer / denom; + result.rem = numer % denom; + + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ - result.quot = (numer / denom) * sign; - result.rem = (numer % denom) * sign; + if (numer >= 0 && result.rem < 0) + { + ++result.quot; + result.rem -= denom; + } - return(result); + return result; } diff --git a/stdlib/ldiv.c b/stdlib/ldiv.c index ecadde31f2..661f1bdbcd 100644 --- a/stdlib/ldiv.c +++ b/stdlib/ldiv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. +/* Copyright (C) 1992 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,6 +16,42 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + #include <ansidecl.h> #include <stdlib.h> @@ -26,14 +62,31 @@ ldiv_t DEFUN(ldiv, (numer, denom), long int numer AND long int denom) { ldiv_t result; - /* Behavior for negative numbers is guaranteed. */ - register long int sign = (numer < 0L) == (denom < 0L) ? 1L : -1L; - numer = numer < 0L ? -numer : numer; - denom = denom < 0L ? -denom : denom; + result.quot = numer / denom; + result.rem = numer % denom; + + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ - result.quot = (numer / denom) * sign; - result.rem = (numer % denom) * sign; + if (numer >= 0 && result.rem < 0) + { + ++result.quot; + result.rem -= denom; + } return result; } |