Formerly stdlib/stdlib.h.~12~
[kopensolaris-gnu/glibc.git] / stdlib / ldiv.c
1 /* Copyright (C) 1992 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB.  If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 /*
20  * Copyright (c) 1990 Regents of the University of California.
21  * All rights reserved.
22  *
23  * This code is derived from software contributed to Berkeley by
24  * Chris Torek.
25  *
26  * Redistribution and use in source and binary forms, with or without
27  * modification, are permitted provided that the following conditions
28  * are met:
29  * 1. Redistributions of source code must retain the above copyright
30  *    notice, this list of conditions and the following disclaimer.
31  * 2. Redistributions in binary form must reproduce the above copyright
32  *    notice, this list of conditions and the following disclaimer in the
33  *    documentation and/or other materials provided with the distribution.
34  * 3. All advertising materials mentioning features or use of this software
35  *    must display the following acknowledgement:
36  *      This product includes software developed by the University of
37  *      California, Berkeley and its contributors.
38  * 4. Neither the name of the University nor the names of its contributors
39  *    may be used to endorse or promote products derived from this software
40  *    without specific prior written permission.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52  * SUCH DAMAGE.
53  */
54
55 #include <ansidecl.h>
56 #include <stdlib.h>
57
58
59 /* Return the `ldiv_t' representation of NUMER over DENOM.  */
60 __CONSTVALUE
61 ldiv_t
62 DEFUN(ldiv, (numer, denom), long int numer AND long int denom)
63 {
64   ldiv_t result;
65
66   result.quot = numer / denom;
67   result.rem = numer % denom;
68
69   /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
70      NUMER / DENOM is to be computed in infinite precision.  In
71      other words, we should always truncate the quotient towards
72      zero, never -infinity.  Machine division and remainer may
73      work either way when one or both of NUMER or DENOM is
74      negative.  If only one is negative and QUOT has been
75      truncated towards -infinity, REM will have the same sign as
76      DENOM and the opposite sign of NUMER; if both are negative
77      and QUOT has been truncated towards -infinity, REM will be
78      positive (will have the opposite sign of NUMER).  These are
79      considered `wrong'.  If both are NUM and DENOM are positive,
80      RESULT will always be positive.  This all boils down to: if
81      NUMER >= 0, but REM < 0, we got the wrong answer.  In that
82      case, to get the right answer, add 1 to QUOT and subtract
83      DENOM from REM.  */
84
85   if (numer >= 0 && result.rem < 0)
86     {
87       ++result.quot;
88       result.rem -= denom;
89     }
90
91   return result;
92 }