Home  Forums  Reviews  Guides  Newsgroups  Register  Search 
Thread Tools 
TTroy 


 
Richard Bos
Guest
Posts: n/a

"TTroy" <(EMail Removed)> wrote:
> Integral Promotion > =================== > All chars and shorts are promoted to int(signed) before any operating > is done on them. If an unsigned short has the same bitsize as int, > then the promotion is to unsigned int. Ditto for unsigned char. It's a rare occasion outside freestanding implementations, though. > char a = 9; > unsigned b = 4; > > a = b + a; /* a and b both converted to int before addition */ > /* the result is then converted back to char by the assignment */ > > So basically, integral promotion gurantees that all intermediate > computations are dealt with nothing "lower" than an int. Am I right? Yes. Unfortunately  I don't like this "feature". > Artihmetic Promotion > ===================== > If the variables involved in an arithmetic operation are all at least > int, then "level" priorities take over. > > The priority is : long double, double, float, long, int > > If one variable involved in a binary operation is a higher "level" than > the other, the other is promoted to that same level. > > After that, the next type of priority is also applied, based on > signed/unsigned. > If one variable is unsigned and the other is signed, the signed is > converted to unsigned. > > Once all this is done, we go on with the binary operation to produce > the result. Am I right? Half. What you've written is correct; but there are similar promotions for the floating point types. Richard 




Richard Bos 


 
Kobu
Guest
Posts: n/a

Richard Bos wrote: > "TTroy" <(EMail Removed)> wrote: > > > Integral Promotion > > =================== > > All chars and shorts are promoted to int(signed) before any operating > > is done on them. If an unsigned short has the same bitsize as int, > > then the promotion is to unsigned int. > > Ditto for unsigned char. It's a rare occasion outside freestanding > implementations, though. > Integral Promotion A char or a short (signed or not) may be used in an expression whenever an integer may be used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. => To add to the OP: When this conversion is done, how many integral variables are taken into consideration for the promotion at a time, and what exactly "expression" means is what all explanations lack. For example (sizeof(short)== 32, sizeof(int) == 32): unsigned short a = 1; signed short b = 45; signed char c = 34; unsigned char d = 21; signed long f = SLONG_MAX; int = e; e = (a*b + c*d) * f; Are all a,b,c,d considered against the intergral promotion rule at once? Or is a&b treated as an independent promotion from c&d? Are all integral promotions in the whole expression finished before any further conversions (based on arirthmetic rules)? These are some of the questions for which I haven't found enlightenment in K&R2 or the standards (not experienced enough to make much sense of the standards). 




Kobu 
Peter Nilsson
Guest
Posts: n/a

Kobu wrote:
> Richard Bos wrote: > > "TTroy" <(EMail Removed)> wrote: > > > > > Integral Promotion > > > =================== > > > All chars and shorts are promoted to int(signed) before any > > > operating is done on them. If an unsigned short has the same > > > bitsize as int, then the promotion is to unsigned int. No. The standard says... "If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int." Bit size is irrelevant. It's the _value_ range that is significant. > > Ditto for unsigned char. It's a rare occasion outside freestanding > > implementations, though. It's arguable whether a hosted implementation where INT_MAX < UCHAR_MAX could ever be conforming. > Integral Promotion > > A char or a short (signed or not) may be used in an expression > whenever an integer may be used. If an int can represent all the > values of the original type, then the value is converted to int; > otherwise the value is converted to unsigned int. > > => To add to the OP: When this conversion is done, how many > integral variables are taken into consideration for the promotion > at a time, and what exactly "expression" means is what all > explanations lack. > > For example (sizeof(short)== 32, sizeof(int) == 32): You have a machine with 32 byte integers! Whatever the size, the range of integer types is constrained, but _not_ determined by the size of the integer. The expression... sizeof(short) > sizeof(int) ....can theoretically evaluate to 1 on a hypothetical conforming implementation. > unsigned short a = 1; > signed short b = 45; > signed char c = 34; > unsigned char d = 21; > signed long f = SLONG_MAX; If you meant LONG_MAX, the later expression is a bad example since the overflow results in undefined behaviour. > int = e; ITYM int e; > > e = (a*b + c*d) * f; > > Are all a,b,c,d considered against the intergral promotion rule at > once? Yes. > Or is a&b treated as an independent promotion from c&d? Are all > integral promotions in the whole expression finished before any > further conversions (based on arirthmetic rules)? Effectively, yes. Though an implementation can achieve this in various ways behind the scenes. [For instance, for the above expression, a given compiler may silently convert all the arguments to long before performing any arithmetic operation, if it can determine that this act won't change a required result.]  Peter 




Peter Nilsson 
S.Tobias
Guest
Posts: n/a

TTroy <(EMail Removed)> wrote:
> difference between the following pairs of terms are: > 1) Integral promotion vs. Arithmetic Conversion > 2) Value Preserving vs. Unsigned Preserving Integral promotions deal only with one type and convert (one) short type to int type. Arithmetic conversions always deal with two types and convert (one or both) the "smaller" type to the "larger" type (their purpose is to establish common type for the operands and the result). > I've read many, many old posts from c.l.c that referred to those 4 > terms constantly.. this is what I think they mean: > Integral Promotion > =================== > All chars and shorts are promoted to int(signed) before any operating > is done on them. All short types, to signed or unsigned int, and only in certain cases, not everywhere. > If an unsigned short has the same bitsize as int, > then the promotion is to unsigned int. Yes. ("Bitsize" is called width.) > Integral promotion is done as an intermediate step for all common > computations. > Ex: > char a = 9; > unsigned b = 4; > a = b + a; /* a and b both converted to int before addition */ Only a is promoted. > /* the result is then converted back to char by the assignment */ Yes, but this time this conversion is neither promotion nor usual arithmetic conversion (UAC). Perhaps more interesting case is this one: char c; long l; c + l; First c is promoted to (signed or unsigned) int type, and then UAC takes place and c is converted again to (signed or unsigned) long type. > So basically, integral promotion gurantees that all intermediate > computations are dealt with nothing "lower" than an int. Am I right? Basically yes. >  > Artihmetic Promotion > ===================== You mean: Usual arithmetic conversion. > If the variables involved in an arithmetic operation are all at least > int, then "level" priorities take over. > The priority is : long double, double, float, long, int For integer types the "level" is called "rank". Into the above list you could throw in long long and extended types. > If one variable involved in a binary operation is a higher "level" than > the other, the other is promoted to that same level. Yes. And you should use "converted"; the word "promoted" is reserved... well... for promotions of course. > After that, the next type of priority is also applied, based on > signed/unsigned. No, this is done at the same time. See below. > If one variable is unsigned and the other is signed, the signed is > converted to unsigned. No. This rule is called "unsigned preserving" (aka "signedness preserving") and was rejected for the "value preserving" rule. See below. > Once all this is done, we go on with the binary operation to produce > the result. Am I right? Yes. >  Value and unsigned preserving conversion rules apply both to promotions and UACs, so we have to consider them together. (Of course, they apply only to integer types for only they have signedness property). They are two options of how to perform conversions between signed and unsigned types. The Standard has chosen value preserving, and rejected unsigned preserving rule. Unsigned preserving rule Whenever one operand is unsigned, all operands are converted to unsigned version of the target type. eg.: promotion: signed char > int unsigned char > unsigned int UAC: unsigned int + long > unsigned long + unsigned long Unsigned preserving rule seems simpler and more predictable, but the Standard has rejected it and it has never applied (only before the Standard, it's in K&R1). Value preserving rule This rule works mostly the same as in unsigned preserving, with one exception: when the "smaller" type is unsigned and the "larger" type is signed. promotion: unsigned char > (signed/unsigned) int UAC: unsigned int + long > (s/u) long + (s/u) long The rule says that: if range(unsigned shorter) c range(signed longer) convert (unsigned shorter) to (signed longer) otherwise convert both to (unsigned longer). (range(type) is set of all possible values of type, 'c' means inclusion.) (Note that in the first case the conversion unsigned>singed is well defined, cf. 6.3.1.3.) To illustrate this rule graphically (promotion only): USHRT_MAX I0SI> promote short to int INT_MIN INT_MAX USHRT_MAX I0IS> promote short to unsigned INT_MIN INT_MAX Value preserving rule is what the Standard has chosen since the beginning. Which of these rules is better is a matter of past discussions. No doubt, "value unsigned preserving Chris Torek" are the best keywords to find them. I don't have my opinion on this issue yet. > Value Preserving > ================ > I am very confused on this term. Does it mean that, say for example, a > conversion from an unsigned short to an int is done, and the value > stored in the unsigned short is larger than the maximum possible > positive number in an int, then the result is implementation defined. > If the value stored in unsigned short is less than the maximum > posssible positive number in an in, then the exact value will exit in > the int (guaranteed to have msb = 0). When USHRT_MAX > INT_MAX, then promote to unsigned. If USHRT_MAX <= INT_MAX, promote to int. This is not implementation defined. The width of types is implementation defined, so we may say that the result is indirectly implementation defined, but it strictly depends on the ranges of both types. > What I don't get about value preserving rules is, whether they are > based on the actual value in variables(run time), or the POSSIBLE > RANGES of the INTEGERS(compile time)? Of course, possible ranges. >  > Unsigned Preserving > =================== > I have a feeling this is a more strict rule (subset of Value > preserving) It's not a subset, both rules are mostly the same, they differ only at one point. > that implies 2's compliment. > Where actual bit patters are > moved without change, as would be the case for 2's compliment. Neither rule concerns the representation. Unsigned preserving demands only that "unsigned" always wins, ie: unsigned + long > both to unsigned long, always and without exception. >  [snip] > only mention "signed extension".. "Sign extension" is about converting values (which is part of conversion operation) in binary representation and it doesn't directly come into what has been said above. This sort of applies _after_ you have established what the target type is. > ... looked at C89 draft.. little too > advanced for a beginner). I know that part (I think of 6.3.1 in C99) is not easy to read, but it is the most accurate explanation I have come across. Read it twice a day, after two weeks it'll seem plain obvious to you.  Stan Tobias mailx `echo http://www.velocityreviews.com/forums/(EMail Removed)LID  sed s/[[:upper:]]//g` 




S.Tobias 
S.Tobias
Guest
Posts: n/a

Peter Nilsson <(EMail Removed)> wrote:
> Kobu wrote: > > unsigned short a = 1; > > signed short b = 45; > > signed char c = 34; > > unsigned char d = 21; > > signed long f = SLONG_MAX; > If you meant LONG_MAX, the later expression is a bad example > since the overflow results in undefined behaviour. > > int = e; > ITYM int e; > > > > e = (a*b + c*d) * f; > > > > Are all a,b,c,d considered against the intergral promotion rule at > > once? > Yes. Of course all promotions can be done at the start, because the results of arithmetic operators are int or above and there's nothing to promote afterwards (unless there's a cast to a short type later on the way). > > Or is a&b treated as an independent promotion from c&d? Are all > > integral promotions in the whole expression finished before any > > further conversions (based on arirthmetic rules)? I got lost here, but I think he means UACs at this point. > Effectively, yes. Though an implementation can achieve this in > various ways behind the scenes. [For instance, for the above > expression, a given compiler may silently convert all the arguments > to long before performing any arithmetic operation, if it can > determine that this act won't change a required result.] I haven't considered exactly the expression, but the answer in genaral seems to me "No": unsigned u1, u2; unsigned long ul; u1 + u2 + ul; First u1 and u2 are added. If the result may overflow in unsigned type. Then the result is converted to unsigned long and ul is added. If all operands were converted at the start before arithmetic operations the resulting value might be different.  Stan Tobias mailx `echo (EMail Removed)LID  sed s/[[:upper:]]//g` 




S.Tobias 
kiru.sengal@gmail.com
Guest
Posts: n/a

> > > Integral Promotion > > =================== > > All chars and shorts are promoted to int(signed) before any operating > > is done on them. > > All short types, to signed or unsigned int, and only in certain cases, > not everywhere. It's ridiculous how integral promotions done. The promotions vary system to system. To me a "rule" like this shouldn't have an IF STATEMENT attached to it (IF it fits, plug it into a signed int, otherwise stuff it into an unsigned int), thus we have to live with the confusions of both experts and beginners. Being someone who works with 8bit, 16bit, 32bit and 64bit micros, this really irritates me  only way to write portable code is with extracautious casting or preprocessor tricks. 




kiru.sengal@gmail.com 
Luke Wu
Guest
Posts: n/a

TTroy wrote: > Hello, I'm relatively new to C and have gone through more than 4 books > on it. None mentioned anything about integral promotion, arithmetic > conversion, value preserving and unsigned preserving. And K&R2 > mentions "signed extension" everywhere. > > Reading some old clc posts, I've beginning to realize that these books > are overgeneralizing the topic. I am just wondering what the > difference between the following pairs of terms are: > > 1) Integral promotion vs. Arithmetic Conversion > 2) Value Preserving vs. Unsigned Preserving > > I've read many, many old posts from c.l.c that referred to those 4 > terms constantly.. this is what I think they mean: > > Integral Promotion > =================== > All chars and shorts are promoted to int(signed) before any operating > is done on them. If an unsigned short has the same bitsize as int, > then the promotion is to unsigned int. > > Integral promotion is done as an intermediate step for all common > computations. Integral Promotion is not a "first pass" that is done on operands before arithmetic conversions. Instead, it's a part of arithmetic conversions (one of the steps). Arithmetic Conversion (C89/90) follows like this: 1. If either operand is long double, the other is converted to long double. 2. Otherwise, if either operand is double, the other is converted to double. 3. Otherwise, if either operand is float, the other is converted to float. 4. Otherwise, the integral promotions are performed on both operands; then if either operand is unsigned long int, the other is converted to unsigned long int. 5. Otherwise, if one operand is long int and the other is unsigned int, the effect depends on whether a long int can represent all values of an unsigned int; if so, the unsigned int operant is converted to long int; if not, both are converted to unsigned long int. 6. Otherwise, if one operand is long int, the other is converted to long int. 7. Otherwise, if either operand is unsigned int, the other is converted to unsigned int. 8. Otherwise, both operands have type int. If you look at step #4 in arithmetic conversions, you will find actions pertaining to integral promotions. So Integral promotions only occur if none of the other operands are of a floating point type (float, double, long double). If the other operand is of a floating point type, there is no integral promotion. If the other operand is not of a floating point type, then all operands are first converted to a minimum of (signed int or unsigned in), then the rest of the integer related arithmetic conversions are done. So, INTEGER PROMOTIONS are ONE STEP in ARITHMETIC PROMOTIONS (and if there are floating point types involved, they aren't even the first step). > > Ex: > > char a = 9; > unsigned b = 4; > > a = b + a; /* a and b both converted to int before addition */ > /* the result is then converted back to char by the assignment */ > > So basically, integral promotion gurantees that all intermediate > computations are dealt with nothing "lower" than an int. Am I right? > Assignments obey different rules (neither Arithmetic Conversions or Integer Promotions apply). in a statement like: a = b; All that happens is b is coerced to a's type, doesn't matter who has a higher rank or whether or no b is at least an int. 




Luke Wu 
Luke Wu
Guest
Posts: n/a

Peter Nilsson wrote: > > Kobu Selva wrote: > > > > > > unsigned short a = 1; > > signed short b = 45; > > signed char c = 34; > > unsigned char d = 21; > > signed long f = LONG_MAX; > > int = e; > > > > e = (a*b + c*d) * f; > > > > Are all a,b,c,d considered against the intergral promotion rule at > > once? > > Yes. > No, not yes. All of them are not considered at once. First of all, integral promotion is not an independent consideration, it's part of the greater Usual Arithmetic Conversions (which includes floating conversion, integral promotion, integer conversions  in that order). The compiler will effectively look at the e = (a*b + c*d) * f expression in steps, as can be explained by this parse tree: .. = .. / \ .. e * .. / \ .. f + .. / \ .. * * .. / \ / \ .. a b c d As you can see, at any instant, the compiler is dealing with only 1 operator and 2 operands. This smallest subexpression is what the compiler performs UAC on (following the steps I outlined in the previous post). So let's say our system has the following characteristic: USHRT_MAX > INT_MAX (unsigned short's range can't fit in a signed integer). Also assume that a & d are characters, b is a signed short and d is an unsigned short. So the compiler will consider each smalled sub expression independently... so let's say the compiler deals with the a * b subexpression first, since there are no floating point types, the first step of UAC that applies to a * b is integral promotions. Since the types of both a & b can fit in a signed int, they are promoted to a signed int (which will be the result of the a * b sub expression). At that point, no further steps of UAC apply, we're done for now. Then let's say the compiler looks at c * d (it could have done this before looking at a * b), the first step of UAC that applies to c * d is integral promotions, since d is an unsigned short and USHRT_MAX > INT_MAX, both c & d are converted to unsigned int, and that is the type of the result. At that point, no futher steps of UAC apply, we're done for now. The next step would be to consider the sub expression held together by the + in the tree (addition of the two results we've figured out from now). Thus, we have the addition of a signed int and an unsigned int. The first step of UAC that applies to this subexpression is the converstion of the signed int to the unsigned int, which will be the type of the result. Then we (or compiler) consider the topmost * in the tree, which multiplies our result from just above with f. The first part of UAC that applies here is the convesion of our result from above (unsigned int) to float, which will be the type of our result. At that point, no further steps of UAC apply (don't even have to consider integral promotion). So this is how we proceed up the tree, only looking at each smallest sub expression (2 operands and 1 operator) when considering UAC. When we reach the = operationg, UAC has no effect on it and conversion of the right side's operands is made to match the type of the left operand (e). So this is how Integral Promotions, UAC, etc. apply to large expressions. Compiler doesn't necessarily have to do everything exactly like this. It can do it any way it wants, but it has to match the behaviour we get from analysing expressions like this. You can't look at a large expression and just say "all the chars, shorts, bitfields will be converted to ______ int" (where ______ is signed or unsigned). Some could be converted in intermediate steps to unsigned int, some could be converted in intermediate steps to signed int. They are taken into consideration in pairs, and integral promotion is only one consideration amongt many that make up UAC (if one of the operands in a smallest subexpression is a floating point type, integral promotion will play no part with either operand). 




Luke Wu 
TTroy
Guest
Posts: n/a

Luke Wu wrote: > Peter Nilsson wrote: > > > > Kobu Selva wrote: > > > > > > > > > unsigned short a = 1; > > > signed short b = 45; > > > signed char c = 34; > > > unsigned char d = 21; > > > signed long f = LONG_MAX; > > > int = e; > > > > > > e = (a*b + c*d) * f; > > > > > > Are all a,b,c,d considered against the intergral promotion rule at > > > once? > > > > Yes. > > > > No, not yes. All of them are not considered at once. First of all, > integral promotion is not an independent consideration, it's part of > the greater Usual Arithmetic Conversions (which includes floating > conversion, integral promotion, integer conversions  in that order). > > The compiler will effectively look at the e = (a*b + c*d) * f > expression in steps, as can be explained by this parse tree: > > . = > . / \ > . e * > . / \ > . f + > . / \ > . * * > . / \ / \ > . a b c d > > As you can see, at any instant, the compiler is dealing with only 1 > operator and 2 operands. This smallest subexpression is what the > compiler performs UAC on (following the steps I outlined in the > previous post). So let's say our system has the following > characteristic: USHRT_MAX > INT_MAX (unsigned short's range can't fit > in a signed integer). > Also assume that a & d are characters, b is a signed short and d is an > unsigned short. > > So the compiler will consider each smalled sub expression > independently... so let's say the compiler deals with the a * b > subexpression first, since there are no floating point types, the first > step of UAC that applies to a * b is integral promotions. Since the > types of both a & b can fit in a signed int, they are promoted to a > signed int (which will be the result of the a * b sub expression). At > that point, no further steps of UAC apply, we're done for now. > > Then let's say the compiler looks at c * d (it could have done this > before looking at a * b), the first step of UAC that applies to c * d > is integral promotions, since d is an unsigned short and USHRT_MAX > > INT_MAX, both c & d are converted to unsigned int, and that is the type > of the result. At that point, no futher steps of UAC apply, we're done > for now. > > The next step would be to consider the sub expression held together by > the + in the tree (addition of the two results we've figured out from > now). Thus, we have the addition of a signed int and an unsigned int. > The first step of UAC that applies to this subexpression is the > converstion of the signed int to the unsigned int, which will be the > type of the result. > > Then we (or compiler) consider the topmost * in the tree, which > multiplies our result from just above with f. The first part of UAC > that applies here is the convesion of our result from above (unsigned > int) to float, which will be the type of our result. At that point, no > further steps of UAC apply (don't even have to consider integral > promotion). > > So this is how we proceed up the tree, only looking at each smallest > sub expression (2 operands and 1 operator) when considering UAC. When > we reach the = operationg, UAC has no effect on it and conversion of > the right side's operands is made to match the type of the left operand > (e). > > So this is how Integral Promotions, UAC, etc. apply to large > expressions. Compiler doesn't necessarily have to do everything > exactly like this. It can do it any way it wants, but it has to match > the behaviour we get from analysing expressions like this. You can't > look at a large expression and just say "all the chars, shorts, > bitfields will be converted to ______ int" (where ______ is signed or > unsigned). Some could be converted in intermediate steps to unsigned > int, some could be converted in intermediate steps to signed int. They > are taken into consideration in pairs, and integral promotion is only > one consideration amongt many that make up UAC (if one of the operands > in a smallest subexpression is a floating point type, integral > promotion will play no part with either operand). If that is the case, I'm never using a short ever in my life. Why would anyone use a short?????? Such variability and doubt for large expressions (and the variability is multiplied along every step of the computation)!!!!! 




TTroy 


 
Thread Tools  


Similar Threads  
Thread  Thread Starter  Forum  Replies  Last Post 
(int) > (unsigned) > (int) or (unsigned) > (int) > (unsigned):I'll loose something?  pozz  C Programming  12  03202011 11:32 PM 
C/C++ language proposal: Change the 'case expression' from "integral constantexpression" to "integral expression"  Adem  C++  42  11042008 12:39 PM 
C/C++ language proposal: Change the 'case expression' from "integral constantexpression" to "integral expression"  Adem  C Programming  45  11042008 12:39 PM 
Usual arithmetic conversions + integral promotion for short?  Niels Dekker (no reply address)  C++  10  05222004 04:09 PM 
Largest value of an unsigned integral type  Dave  C++  3  11072003 06:51 AM 
Powered by vBulletin®. Copyright ©2000  2014, vBulletin Solutions, Inc..
SEO by vBSEO ©2010, Crawlability, Inc. 