[comp.std.c] div

steve@unidata.ucar.edu (Steve Emmerson) (04/10/91)

Hi,

Would someone who knows please tell me the behavior of div() and ldiv()?

My POSIX book says nothing, and my K&R2 only states that they return
the quotient and remainder of the `numer' and `denom' arguments in the
`quot' and `rem' members of their associated structure types.

I know what this means when both arguments are positive, but I'm uncertain
what this means for the other three cases.  I you would tell me, I would
appreciate it.

Thanks in advance.

Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve

henry@zoo.toronto.edu (Henry Spencer) (04/10/91)

In article <10989@ncar.ucar.edu> steve@unidata.ucar.edu (Steve Emmerson) writes:
>I know what this means when both arguments are positive, but I'm uncertain
>what this means for the other three cases.

For the normal division operator, the results are machine-specific.  For
div() and ldiv(), however, the quotient is truncated towards zero.
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

darcy@druid.uucp (D'Arcy J.M. Cain) (04/11/91)

In article <10989@ncar.ucar.edu> Steve Emmerson writes:
>Would someone who knows please tell me the behavior of div() and ldiv()?
>[...]
>I know what this means when both arguments are positive, but I'm uncertain
>what this means for the other three cases.  I you would tell me, I would
>appreciate it.

I happened to have given this some thought recently and although there
doesn't seem to be any standard mandated behaviour as far as I can tell
here is what I came up with in an implementation:

--------------------------- start of div.c ----------------------------
/*
 * div.c
 * Written by D'Arcy J.M. Cain
 * note LDIV_SUB defined turns this into ldiv()
 *
 * This is part of my effort to collect all the routines that
 * comprise the ANSI standard library in one place.  These routines
 * are public domain unless specifically stated otherwise in a
 * source file.
 */

/*
What does div and ldiv do with negative numbers?  Working backwards from
the observation that when positive numbers are involved, the remainder
added to the product of the quotient and denominator should give the
numerator, I get the following examples:

    num   denom    quot    rem
    ===   =====    ====    ===
    +13      +5      +2     +3
    -13      +5      -2     -3
    +13      -5      -2     +3
    -13      -5      +2     -3

if denom is 0 then I return qotient as 0 and remainder as the numerator.
That seems to fit the model: (0 * 0) + rem == num.

*/

#include <stdlib.h>

#ifdef	LDIV_SUB
ldiv_t	ldiv(long num, long denom)
{
	ldiv_t r;
#else
div_t	div(int num, int denom)
{
	div_t r;
#endif	/* LDIV_SUB */

	int sr, sq;

	if (!denom)
	{
		r.quot = 0;
		r.rem = num;
		return(r);
	}

	if (num < 0)
	{
		sr = -1;
		num = -num;
	}
	else
		sr = 1;

	if (denom < 0)
	{
		sq = sr * -1;
		denom = -denom;
	}
	else
		sq = sr;

	r.quot = num / denom * sq;
	r.rem = (num % denom) * sr;
	return (r);
}
------------------------------------------------------------------------

Hope this helps.

-- 
D'Arcy J.M. Cain (darcy@druid)     |
D'Arcy Cain Consulting             |   There's no government
Toronto, Ontario, Canada           |   like no government!
+1 416 424 2871                    |

henry@zoo.toronto.edu (Henry Spencer) (04/11/91)

In article <1991Apr10.181921.20661@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes:
>I happened to have given this some thought recently and although there
>doesn't seem to be any standard mandated behaviour...

Ahem.  Wrong.  RTFS. :-)
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

browns@iccgcc.decnet.ab.com (Stan Brown) (04/16/91)

In article <10989@ncar.ucar.edu>, steve@unidata.ucar.edu (Steve Emmerson) writes:
> Would someone who knows please tell me the behavior of div() and ldiv()?
> 
> I know what this means when both arguments are positive, but I'm uncertain
> what this means for the other three cases.  I you would tell me, I would

Sec 4.10.6.2 of the standard says that div(int numer, int denom)
"computes the quotient and  remainder of the division of the numerator
numer by the denominator denom.  If the division is inexact, the
resulting quotient is the integer of lesser magnitude that is nearest to
the algebraic quotient.  If the result [can] be represented, ... 
quot * denom + rem shall equal numer."

This means, as I read it, that the quotient is always truncated toward
zero.  Thus,
	div(8,3)   gives quot=2,  rem=2
	div(8,-3)  gives quot=-2, rem=2
	div(-8,3)  gives quot=-2, rem=-2
	div(-8,-3) gives quot=2,  rem=-2
There's a similar table in sec 4.10.6.2 of the rationale, with 7
substituted for 8 and 1's or -1's for the remainders.

BTW, note that this is may be different from the result of 8/(-3) etc.
Sec 3.3.5 says the result can be -2 or -3 (implementation-defined).

Stan Brown, Oak Road Systems, Cleveland, Ohio, USA    +1 216 371 0043
                   email (until 91/4/30): browns@iccgcc.decnet.ab.com
My opinions are mine:  I don't speak for any other person or company.