summaryrefslogtreecommitdiff
path: root/libc/stdlib/lldiv.c
blob: 166bd46e42efb5dfbeaf659e02ea995bf0a5d2af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/* `long long int' divison with remainder.
   Copyright (C) 1992, 1996, 1997 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
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <features.h>
#include <stdlib.h>


/* Return the `lldiv_t' representation of NUMER over DENOM.  */
lldiv_t
lldiv (long long int numer, long long int denom)
{
    lldiv_t result;

    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.  */

    if (numer >= 0 && result.rem < 0)
    {
	++result.quot;
	result.rem -= denom;
    }

    return result;
}

#if __WORDSIZE != 64
#undef imaxdiv
strong_alias(lldiv,imaxdiv)
#endif