xref: /openbmc/u-boot/lib/ldiv.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
278acc472SPeter Tyser /* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
378acc472SPeter Tyser    This file is part of the GNU C Library.
4a53002f4SWolfgang Denk  */
578acc472SPeter Tyser 
678acc472SPeter Tyser typedef struct {
778acc472SPeter Tyser 	long    quot;
878acc472SPeter Tyser 	long    rem;
978acc472SPeter Tyser } ldiv_t;
1078acc472SPeter Tyser /* Return the `ldiv_t' representation of NUMER over DENOM.  */
1178acc472SPeter Tyser ldiv_t
ldiv(long int numer,long int denom)1278acc472SPeter Tyser ldiv (long int numer, long int denom)
1378acc472SPeter Tyser {
1478acc472SPeter Tyser   ldiv_t result;
1578acc472SPeter Tyser 
1678acc472SPeter Tyser   result.quot = numer / denom;
1778acc472SPeter Tyser   result.rem = numer % denom;
1878acc472SPeter Tyser 
1978acc472SPeter Tyser   /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
2078acc472SPeter Tyser      NUMER / DENOM is to be computed in infinite precision.  In
2178acc472SPeter Tyser      other words, we should always truncate the quotient towards
2278acc472SPeter Tyser      zero, never -infinity.  Machine division and remainer may
2378acc472SPeter Tyser      work either way when one or both of NUMER or DENOM is
2478acc472SPeter Tyser      negative.  If only one is negative and QUOT has been
2578acc472SPeter Tyser      truncated towards -infinity, REM will have the same sign as
2678acc472SPeter Tyser      DENOM and the opposite sign of NUMER; if both are negative
2778acc472SPeter Tyser      and QUOT has been truncated towards -infinity, REM will be
2878acc472SPeter Tyser      positive (will have the opposite sign of NUMER).  These are
2978acc472SPeter Tyser      considered `wrong'.  If both are NUM and DENOM are positive,
3078acc472SPeter Tyser      RESULT will always be positive.  This all boils down to: if
3178acc472SPeter Tyser      NUMER >= 0, but REM < 0, we got the wrong answer.  In that
3278acc472SPeter Tyser      case, to get the right answer, add 1 to QUOT and subtract
3378acc472SPeter Tyser      DENOM from REM.  */
3478acc472SPeter Tyser 
3578acc472SPeter Tyser   if (numer >= 0 && result.rem < 0)
3678acc472SPeter Tyser     {
3778acc472SPeter Tyser       ++result.quot;
3878acc472SPeter Tyser       result.rem -= denom;
3978acc472SPeter Tyser     }
4078acc472SPeter Tyser 
4178acc472SPeter Tyser   return result;
4278acc472SPeter Tyser }
43