Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!sdrc!thor!scjones From: scjones@thor.UUCP (Larry Jones) Newsgroups: comp.unix.i386 Subject: Re: Is this (gasp) a chip bug? Summary: No. Message-ID: <121@thor.UUCP> Date: 30 Jul 90 14:48:56 GMT References: <1990Jul23.223341.26431@cbnewsc.att.com> Distribution: na Organization: SDRC, Cincinnati Lines: 42 In article <1990Jul23.223341.26431@cbnewsc.att.com>, imdave@cbnewsc.att.com (david.e.bodenstab) writes: < main() < { < unsigned y = 0x7ffff0ff; < unsigned x = 0x7ffff000; < < while (1) { < if ( ((int)(y - x)) < 0 ) < printf("WRONG x=%x y=%x (y - x)=%x\n",x,y,y-x); < x++; < y++; < } < } < < This program `fails' on both a 386 and another cpu in-house -- the < range of values for the `failure' are: < 0x80000000 <= y <= 0x800000fe < 0x7fffff01 <= x <= 0x7fffffff < The assembly instructions generated for both cpu's were: < sub x from y < bge skip # branch greater than or equal < push args for printf... < call printf < skip: That's a code generation error, although not an obvious one. Those instructions corresponds to "if ((int)y - (int)x < 0)" which is not, of course, what you wanted. bge fails because you have taken a large negative number and subtracted a large positive number which results in a very large negative number which overflows. The correct instruction would be bns (branch not sign) since you really just want to test the sign of the final result. I suspect that using a temporary variable to hold the intermediate result rather than counting on the cast the compiler will do the right thing. ---- Larry Jones UUCP: uunet!sdrc!thor!scjones SDRC scjones@thor.UUCP 2000 Eastman Dr. BIX: ltl Milford, OH 45150-2789 AT&T: (513) 576-2070 "This probably just goes to show something, but I sure don't know what." -Calvin