Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!uunet!mcvax!kth!draken!tut!santra!tukki!tarvaine From: tarvaine@tukki.jyu.fi (Tapani Tarvainen) Newsgroups: comp.lang.c Subject: Re: Detecting overflow Message-ID: <723@tukki.jyu.fi> Date: 20 May 89 08:08:10 GMT References: <455@skye.ed.ac.uk> Reply-To: tarvaine@tukki.jyu.fi (Tapani Tarvainen) Organization: University of Jyvaskyla, Finland Lines: 60 In article <455@skye.ed.ac.uk> ken@aiai.UUCP (Ken Johnson) writes: [about detecting overflow in integer multiplication] > if ( b != 0 && (a * b)/b == a) { /* No overflow */ } > >However, this is not always going to work. Consider the case of >a = 512 (0x200), b = 64 (0x40). Then in 16-bit arithmetic, > > a != 0 is true > b != 0 is true > (a * b) = 0x8000 (overflowing) but 0x8000/0x40 = 0x200 > >...so I don't think this is guaranteed to work either. If you're doing unsigned multiplication the above isn't overflow, if signed then division is presumably signed also and 0x08000/0x040 = -32768/-64 = -512 = 0x0FE00 != 0x0200. Actually I'm not at all sure signed multiplication gives the above result in all processors, or indeed that any particular result can be relied on. Nonetheless, the test works even if we assume that a random number is generated whenever overflow occurs: If c/b == a && c%b == 0 then c == a*b, without overflow, as long as division can be relied on. Moreover, if a*b overflows, then c/b == a && c%b != 0 isn't possible. 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) (in one's complement arithmetic it NEVER overflows) so if -32768*-1 gives -32768 and -32768/-1 also gives -32768 then the test will fail. The truly paranoid can can test for this possibility separately, e.g., a<0 && -a<0 doesn't take much time. Of course there's still the possibility that a too smart compiler will optimize (a*b)/b as a ... but if you write it as c = a * b; if (c / b != a) { /* overflow */ ... you should be safe; if ((c = a * b) / b != a) { ... is probably OK as well (anybody know what pANS says about expression optimization in cases like this?). Finally: All this assumes multiplication can only result in normal numbers - if there is an architecture with integer NaNs or something which can result from multiplication overflow but isn't guaranteed to work reasonably in division, then all bets are off. (E.g., if 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.) -- Tapani Tarvainen BitNet: tarvainen@finjyu Internet: tarvainen@jylk.jyu.fi -- OR -- tarvaine@tukki.jyu.fi