Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site fluke.UUCP Path: utzoo!linus!decvax!microsoft!fluke!roger From: roger@fluke.UUCP (Roger Ferrel) Newsgroups: net.lang.c Subject: Re: problem in type conversion Message-ID: <1302@vax4.fluke.UUCP> Date: Wed, 4-Jan-84 14:57:14 EST Article-I.D.: vax4.1302 Posted: Wed Jan 4 14:57:14 1984 Date-Received: Fri, 6-Jan-84 04:17:32 EST References: <1603@randvax.ARPA> Organization: John Fluke Mfg. Co., Everett, Wash Lines: 74 What we see here with the: inttype *= 0.5; vs inttype = inttype * 0.5; is a weekness of most C compilers. It seems none of them handles float operations very well when there are mixed types. Of course the above is a poor example since normally more efficent code would be generated by using: intype >>= 1; /* how is this for getting off the subject? */ Whenever coding in C I avoid floats and doubles as much as possible. When using them in an expression I usually make sure to explicitly cast everything to doubles and I tend to stay away from the "fancy" assignment operators in mixed type expressions. Thus for the first example I would code: inttype = (int) ( ((double) inttype) * ((double) 0.5)); I know it looks messy but many C compilers need the hints to generate proper code. Rules to follow: 1) In an expression with mixed type explicitly cast operands to biggest type in the expression since this will be the size of the result. (Especially if the largest type is a double.) Types largest to smallest are: double, long, int, short, char Many C compilers convert smaller types to int before doing anything with them in an expression. Floats (single precision) should always be cast to double since C supports double operations but not single. To find out how good your compiler is with mixed operands look at the code produced for: float f; int i; f *= i; /* f and i should be cast to doubles and the * result reduced to single precision float */ 2) Explicitly cast the result of an expression to the same type as the target variable when the target is of smaller type then the expression. (This is being very conservative.) 3) If the expression will be of smaller type then the variable the result is assigned to cast each operand of the expression to the type of the variable you are doing the assignment to. This will avoid unplanned trucation errors. Example: int i; double d; d = (double) i / (double) 17; Following these rules avoids the implicit cast bugs in many C compilers. In practice most compilers do a good job of casting as long as you stick with the various types of integers. When you start using floats and doubles that is the time to follow the above rules closely. -- ------ Roger L. Ferrel (206) 356-5056 John Fluke Mfg. Co. P.O. Box C9090 Everett WA 98206 {uw-beaver,decvax!microsof,ucbvax!lbl-csam,allegra,ssc-vax}!fluke!roger