Detecting overflow

Tim McDaniel mcdaniel at uicsrd.csrd.uiuc.edu
Sun May 21 05:23:56 AEST 1989


In article <455 at skye.ed.ac.uk> ken at aiai.UUCP (Ken Johnson) writes:
: [about detecting overflow in integer multiplication]
:	if ( b != 0 && (a * b)/b == a) { /* No overflow */ }

In article <723 at tukki.jyu.fi> tarvaine at tukki.jyu.fi (Tapani Tarvainen) writes:
>Nonetheless, the test works even if we assume that a random number is
>generated whenever overflow occurs ... as long as division can be
>relied on.

I answered this in another posting.  Basically, "division can't be
relied on" for negative divisors.

>Division can overflow in 2's complement arithmetic in one case only,
>namely when the most negative number is divided by -1 (e.g.,
>-32768/-1 with 16 bits) ... The truly paranoid can can test
>for this possibility separately, e.g., a<0 && -a<0
>doesn't take much time.

In such a case, -a == -INT_MIN overflows, which could trap.  In my
code, I checked for all cases in which -1 is an operand.  The check is
much easier to do and generating the result is much faster.

>Of course there's still the possibility that a too smart compiler
>will optimize (a*b)/b as a ...

One of the most heatedly-debated issues in the ANSI C standardization
effort was whether it should be legal to optimize past parenthesis
boundaries.  Existing practice was that it was legal, and it was
proposed that the unary "+" operator would disable optimization.  In
this case, the expression above would have had to write "+(a*b)/b" to
assure the desired behavior.  After much debate, it was decided to
follow the FORTRANish rule to make it illegal.

Thus, a pANS C-compliant compiler can't be "too smart" here.  Under
pANS C, "(a*b)/b" cannot be optimized to "a".  However, if it's not
pANS C-compliant, all bets are off.  (That's the reason for having a
standard in the first place, so that at least SOME bets can be made.
:-)

>integers are stored as 64 bits but behave as 48-bit ones, except when
>overflow occurs ... I vaguely remember having heard of such a
>system.)

Working from memory here: I think one such system was the CDC Cyber
174 and 175.  Floating-point numbers were 64 bits long, with a 15 bit
exponent field.  The "mantissa" field was not a fraction, as on most
systems today, but an integer.  These were ones-complement machines.
Therefore, the f.p. value was just
        mant_sign * (mantissa * 2 ** (exp_sign * exponent))

So integers were simply floating-point numbers with an exponent of 0.
I'm not sure whether there were any special integer instructions, or
whether floating-point instructions were used instead.  In the latter
case, overflow would have ... interesting ... effects.  Any loop
counter being incremented by 1 that overflowed (overflew? :-) would
hit INT_MAX+1 and stick there.

--
"6:20 O Timothy, keep that which is committed to thy trust, avoiding
profane and vain babblings, and oppositions of science falsely so
called: 6:21 Which some professing have erred concerning the faith."

Tim, the Bizarre and Oddly-Dressed Enchanter  |  mcdaniel at uicsrd.csrd.uiuc.edu
            {uunet,convex,pur-ee}!uiucuxc!uicsrd!mcdaniel
            mcdaniel%uicsrd@{uxc.cso.uiuc.edu,uiuc.csnet}



More information about the Comp.lang.c mailing list