Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 May 2016 14:24:43 -0700
From:      Chris Torek <torek@torek.net>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        Andrey Chernov <ache@freebsd.org>, pfg@freebsd.org, src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r300956 - head/lib/libc/stdlib
Message-ID:  <201605312124.u4VLOhnI085631@elf.torek.net>
In-Reply-To: Your message of "Tue, 31 May 2016 19:58:47 %2B1000." <20160531185907.Y2047@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
>That was what I was complaining about.  div.c is for C90 (misspelled
>"ANSI").

It wasn't misspelled when I wrote it.  :-)  The 1989 ANSI C
standard was formally ratified in Dec 1989, and the draft was
pretty firm by the time I wrote the code (which I am sure was also
1989, despite the 1990 copyright; we added or updated all the
copyrights at the last minute, for net-2).  ISO's quick adoption,
and hence the name C90, post-date all of that.

>... div.c hasn't caught up with C99.  C99 broke this by changing
>the rules for integer division to disallow correct rounding for and
>require consistently incorrect rounding.

Specifically, C99 requires truncation towards zero, so that
(-1)/2 = 0 (not -1) and 1/(-2) = 0 (not -1).  You (and I) might
prefer (-1)/2 = -1, but most CPU "integer divide" ops provide
the other result (so that "x >> 1" and "x / 2" are different
when x is negative: "x >> 1" sign extends so that (-1)>>1 == -1).

C90 (and C99) both require div() and ldiv() to behave like most
CPUs, this this truncation-towards-zero behavior, which makes
the two functions kind of pointless in C99.

>Correct rounding for a
>positive divisor is towards minus infinity so that the remainder is
>not negative.  This is modulo arithmetic and has good algebraic
>properties.  C99 requires rounding minus infinity, at least for positive
>divisors, under the extension "reliable integer division".

Did you state this backwards?  For integer divison I see:

    When integers are divided, the result of the / operator is the
    algebraic quotient with any fractional part discarded.[105] If
    the quotient a/b is representable, the expression (a/b)*b + a%b
    shall equal a; otherwise, the behavior of both a/b and a%b is
    undefined.

which (as footnote 105 notes) is "truncation towards zero", so that
(-1)/2 is 0 and not -1.

>In C90,
>the rounding is implementation-defined, so it may be correct, but it
>is "unreliable" since it can be anything.
>
>In C90, div() is specified as giving "reliable" division, and that is
>what the fixups implement.  This now wastes time to change nothing.

Right -- as long as the compiler must meet C99 rules, div.c
can just use the / and % operators.

Chris



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605312124.u4VLOhnI085631>