Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!columbia!rutgers!mtune!codas!cpsc6a!rtech!wrs!dg From: dg@wrs.UUCP (David Goodenough) Newsgroups: comp.lang.c Subject: Re: MSC C arithmetic Message-ID: <305@wrs.UUCP> Date: Mon, 17-Aug-87 14:12:02 EDT Article-I.D.: wrs.305 Posted: Mon Aug 17 14:12:02 1987 Date-Received: Fri, 21-Aug-87 07:28:52 EDT References: <8792@brl-adm.ARPA> Reply-To: dg@wrs.UUCP (David Goodenough) Organization: Wind River Systems, Emeryville, CA Lines: 67 In article <8792@brl-adm.ARPA> jdickson@zook.Jpl.Nasa.GOV (Jeff Dickson) writes: > ..... stuff deleted ..... > One of the expressions involved multiplying two integers >and placing the result in a long integer. The code looked something >like this: > > unsigned int repeat_cnt; > unsigned int units; > unsigned long n; > > for (n = repeat_cnt * units; n > 0; n--) > > If repeat_cnt equaled 10,000 and units equaled 10, n did >not get set to 100,000! Rather n got set to 34,464 - which is what >the result would be if n were an int not a long (100,000 - 65,536). Your MSC C compiler is behaving correctly. If you read page 41 of the gospel according to Kernighan and Ritchie :-) it says: char & short are converted to int ...... . . . Otherwise if either operand is long, the other is converted to long, and the result is long. . . . Otherwise the operands must be int, and the result is int. The practical upshot of this is that the type of an expression is determined from the operands, NOT the result, i.e. without a cast the multiplication is done as int, not long. It then goes on to say that conversions take place across assignments: the value of the RHS is converted to the type of the LHS, which is the type of the result. BUT SINCE '*' has a higher priority than '=', the mult is still done as int: long assignment = / \ long / \ int converted to long / \ n * int multiplication / \ int / \ int / \ repeat_cnt units The reason this works on the Sun is that on most 68K machines ints and longs are the same size: 32 bits. The second example fails because '*' groups left to right (see page 49 of the gospel according to Kernighan and Ritchie :-) and it does the two integer multiplications first, and then the float (i.e. double). This should work correctly if you wrap the last multiplication in parentheses: > total_bits = repeat_cnt * (units * (blksiz * 16.0)); as this then forces all multiplications to have one float operand, hence getting the desired result. -- dg@wrs.UUCP - David Goodenough +---+ | +-+-+ +-+-+ | +---+