|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Question 3.15:
Why does the code double degC, degF; degC = 5 / 9 * (degF - 32); keep giving me 0? Would the following rearrangement solve the problem? degC = 5 * (degF - 32) / 9; Topi Linkala -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." - Bertrand Russell "How come he didn't put 'I think' at the end of it?" - Anonymous |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote:
> Question 3.15: > > Why does the code > > double degC, degF; > degC = 5 / 9 * (degF - 32); > > keep giving me 0? > > Would the following rearrangement solve the problem? > > degC = 5 * (degF - 32) / 9; > Did you read the answer to the question (<http://c-faq.com/expr/ truncation1.html>)? -- Robert Gamble |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Robert Gamble wrote:
> On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: > >>Question 3.15: >> >>Why does the code >> >>double degC, degF; >>degC = 5 / 9 * (degF - 32); >> >>keep giving me 0? >> >>Would the following rearrangement solve the problem? >> >>degC = 5 * (degF - 32) / 9; >> > > > Did you read the answer to the question (<http://c-faq.com/expr/ > truncation1.html>)? Yes I read and it says: "If both operands of a binary operator are integers, C performs an integer operation,..." But in my rewriting there are no binary operation with integer values. That's why I'm asking if it would work. Topi -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." - Bertrand Russell "How come he didn't put 'I think' at the end of it?" - Anonymous |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Apr 13, 3:48 pm, Topi Linkala <n...@iki.fi> wrote:
> Robert Gamble wrote: > > On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: > > >>Question 3.15: > > >>Why does the code > > >>double degC, degF; > >>degC = 5 / 9 * (degF - 32); > > >>keep giving me 0? > > >>Would the following rearrangement solve the problem? > > >>degC = 5 * (degF - 32) / 9; > > > Did you read the answer to the question (<http://c-faq.com/expr/ > > truncation1.html>)? > > Yes I read and it says: > > "If both operands of a binary operator are integers, C performs an > integer operation,..." > > But in my rewriting there are no binary operation with integer values. > That's why I'm asking if it would work. > Sorry, I missed the fact that degF was a double. Yes, your example will work properly since the division will be happening on floating point values. -- Robert Gamble |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Topi Linkala wrote, On 13/04/08 20:48:
> Robert Gamble wrote: > >> On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: >> >>> Question 3.15: >>> >>> Why does the code >>> >>> double degC, degF; >>> degC = 5 / 9 * (degF - 32); >>> >>> keep giving me 0? >>> >>> Would the following rearrangement solve the problem? >>> >>> degC = 5 * (degF - 32) / 9; >> >> Did you read the answer to the question (<http://c-faq.com/expr/ >> truncation1.html>)? > > Yes I read and it says: > > "If both operands of a binary operator are integers, C performs an > integer operation,..." Which is why it does not work. > But in my rewriting there are no binary operation with integer values. Which is why it would work. > That's why I'm asking if it would work. You obviously did not make it clear enough to Robert that you had read it. Don't worry about it. -- Flash Gordon |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Topi Linkala wrote:
> Robert Gamble wrote: > >> On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: >> >>> Question 3.15: >>> >>> Why does the code >>> >>> double degC, degF; >>> degC = 5 / 9 * (degF - 32); >>> >>> keep giving me 0? >>> >>> Would the following rearrangement solve the problem? >>> >>> degC = 5 * (degF - 32) / 9; >>> >> >> >> Did you read the answer to the question (<http://c-faq.com/expr/ >> truncation1.html>)? > > Yes I read and it says: > > "If both operands of a binary operator are integers, C performs an > integer operation,..." > > But in my rewriting there are no binary operation with integer values. > That's why I'm asking if it would work. > > Topi The statement.. degC = 5 / 9 * (degF - 32); ...can't work because 5 / 9 is (int) zero. Also degF is not initialized. degC = (degF - 32) * 5 / 9; should work better for you. -- Joe Wright "Everything should be made as simple as possible, but not simpler." --- Albert Einstein --- |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Joe Wright wrote:
> Topi Linkala wrote: > >> Robert Gamble wrote: >> >>> On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: >>> >>>> Question 3.15: >>>> >>>> Why does the code >>>> >>>> double degC, degF; >>>> degC = 5 / 9 * (degF - 32); >>>> >>>> keep giving me 0? >>>> >>>> Would the following rearrangement solve the problem? >>>> >>>> degC = 5 * (degF - 32) / 9; >>>> >>> >>> >>> Did you read the answer to the question (<http://c-faq.com/expr/ >>> truncation1.html>)? >> >> >> Yes I read and it says: >> >> "If both operands of a binary operator are integers, C performs an >> integer operation,..." >> >> But in my rewriting there are no binary operation with integer values. >> That's why I'm asking if it would work. >> >> Topi > > > The statement.. > > degC = 5 / 9 * (degF - 32); > > ..can't work because 5 / 9 is (int) zero. Also degF is not initialized. > > degC = (degF - 32) * 5 / 9; > > should work better for you. > I don't think so because there's no reason to believe that the multiplication is done before the division, but in my example that doesn't matter as one of the operands is double in any case. Topi -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." - Bertrand Russell "How come he didn't put 'I think' at the end of it?" - Anonymous |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Apr 13, 4:53 pm, Topi Linkala <n...@iki.fi> wrote:
> Joe Wright wrote: > > Topi Linkala wrote: > > >> Robert Gamble wrote: > > >>> On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: > > >>>> Question 3.15: > > >>>> Why does the code > > >>>> double degC, degF; > >>>> degC = 5 / 9 * (degF - 32); > > >>>> keep giving me 0? > > >>>> Would the following rearrangement solve the problem? > > >>>> degC = 5 * (degF - 32) / 9; > > >>> Did you read the answer to the question (<http://c-faq.com/expr/ > >>> truncation1.html>)? > > >> Yes I read and it says: > > >> "If both operands of a binary operator are integers, C performs an > >> integer operation,..." > > >> But in my rewriting there are no binary operation with integer values. > >> That's why I'm asking if it would work. > > >> Topi > > > The statement.. > > > degC = 5 / 9 * (degF - 32); > > > ..can't work because 5 / 9 is (int) zero. Also degF is not initialized. > > > degC = (degF - 32) * 5 / 9; > > > should work better for you. > > I don't think so because there's no reason to believe that the > multiplication is done before the division, but in my example that > doesn't matter as one of the operands is double in any case. Actually, the multiplication is guaranteed to be performed before the division because they both have the same precedence and are left-to- right associative. -- Robert Gamble |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Topi Linkala wrote:
>> >> degC = (degF - 32) * 5 / 9; >> >> should work better for you. >> > > I don't think so because there's no reason to believe that the > multiplication is done before the division, but in my example that > doesn't matter as one of the operands is double in any case. The operator associativity rules of C language (derived from the grammar) immediately require that the result of this expression should be equal to '(degF - 32) * 5' divided by '9'. The compiler is free to evaluate it in any order as long as the result is correct. Even if it decides to do '5 / 9' first, it is, of course, not allowed to truncate the result. -- Best regards, Andrey Tarasevich |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
Topi Linkala wrote:
> > Question 3.15: > > Why does the code > double degC, degF; > degC = 5 / 9 * (degF - 32); > keep giving me 0? Think about it. 5 and 9 are ints. What is the value of 5/9?. How many times can you subtract 9 from 5 and have the result non-negative? What is the result of that multiplied by (degF -32)? > > Would the following rearrangement solve the problem? > degC = 5 * (degF - 32) / 9; That depends on the type of degF. For double, yes. Much simpler to use 5/9.0. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com ** |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
CBFalconer wrote:
> Topi Linkala wrote: >> Question 3.15: >> >> Why does the code >> double degC, degF; >> degC = 5 / 9 * (degF - 32); >> keep giving me 0? > > Think about it. 5 and 9 are ints. What is the value of 5/9?. How > many times can you subtract 9 from 5 and have the result > non-negative? What is the result of that multiplied by (degF -32)? > >> Would the following rearrangement solve the problem? >> degC = 5 * (degF - 32) / 9; > > That depends on the type of degF. If you read the OP, degF was declared as double. -- Ian Collins. |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
"Topi Linkala" <nes@iki.fi> wrote in message
news:fttrto$elc$1@nyytiset.pp.htv.fi... > Joe Wright wrote: > >> Topi Linkala wrote: >> >>> Robert Gamble wrote: >>> >>>> On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: >>>> >>>>> Question 3.15: >>>>> >>>>> Why does the code >>>>> >>>>> double degC, degF; >>>>> degC = 5 / 9 * (degF - 32); >>>>> >>>>> keep giving me 0? >>>>> >>>>> Would the following rearrangement solve the problem? >>>>> >>>>> degC = 5 * (degF - 32) / 9; >>>>> >>>> >>>> >>>> Did you read the answer to the question (<http://c-faq.com/expr/ >>>> truncation1.html>)? >>> >>> >>> Yes I read and it says: >>> >>> "If both operands of a binary operator are integers, C performs an >>> integer operation,..." >>> >>> But in my rewriting there are no binary operation with integer values. >>> That's why I'm asking if it would work. >>> >>> Topi >> >> >> The statement.. >> >> degC = 5 / 9 * (degF - 32); >> >> ..can't work because 5 / 9 is (int) zero. Also degF is not initialized. >> >> degC = (degF - 32) * 5 / 9; >> >> should work better for you. >> > > I don't think so because there's no reason to believe that the > multiplication is done before the division, but in my example that doesn't > matter as one of the operands is double in any case. More important than the order here is the types. By automatic promotions, all of the mathematical operations you see here take place as double: (double - int) performed as (double-double) returns double value double * int performed as double * double returns double value double / int performed as double / double returns double value From ISO/IEC 9899:1999 (E): "6.3.1.8 Usual arithmetic conversions 1 Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise. This pattern is called the usual arithmetic conversions: First, if the corresponding real type of either operand is long double, the other operand is converted, without change of type domain, to a type whose corresponding real type is long double. Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain, to a type whose corresponding real type is double. Otherwise, if the corresponding real type of either operand is float, the other operand is converted, without change of type domain, to a type whose corresponding real type is float.51) Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands: If both operands have the same type, then no further conversion is needed. Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank. Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type. Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. 2 The values of floating operands and of the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.52) Footnote 51) For example, addition of a double _Complex and a float entails just the conversion of the float operand to double (and yields a double _Complex result). Footnote 52) The cast and assignment operators are still required to perform their specified conversions as described in 6.3.1.4 and 6.3.1.5." You can summarize the general idea of the promotions as "if an operation takes place between wide and narrow, perform using wide and wide instead" ** Posted from http://www.teranews.com ** |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Dann Corbit wrote:
> "Topi Linkala" <nes@iki.fi> wrote in message > news:fttrto$elc$1@nyytiset.pp.htv.fi... > >>Joe Wright wrote: >> >> >>>Topi Linkala wrote: >>> >>> >>>>Robert Gamble wrote: >>>> >>>> >>>>>On Apr 13, 3:33 pm, Topi Linkala <n...@iki.fi> wrote: >>>>> >>>>> >>>>>>Question 3.15: >>>>>> >>>>>>Why does the code >>>>>> >>>>>>double degC, degF; >>>>>>degC = 5 / 9 * (degF - 32); >>>>>> >>>>>>keep giving me 0? >>>>>> >>>>>>Would the following rearrangement solve the problem? >>>>>> >>>>>>degC = 5 * (degF - 32) / 9; >>>>>> >>>>> >>>>> >>>>>Did you read the answer to the question (<http://c-faq.com/expr/ >>>>>truncation1.html>)? >>>> >>>> >>>>Yes I read and it says: >>>> >>>>"If both operands of a binary operator are integers, C performs an >>>>integer operation,..." >>>> >>>>But in my rewriting there are no binary operation with integer values. >>>>That's why I'm asking if it would work. >>>> >>>>Topi >>> >>> >>>The statement.. >>> >>> degC = 5 / 9 * (degF - 32); >>> >>>..can't work because 5 / 9 is (int) zero. Also degF is not initialized. >>> >>> degC = (degF - 32) * 5 / 9; >>> >>>should work better for you. >>> >> >>I don't think so because there's no reason to believe that the >>multiplication is done before the division, but in my example that doesn't >>matter as one of the operands is double in any case. > > > More important than the order here is the types. > By automatic promotions, all of the mathematical operations you see here > take place as double: > > (double - int) performed as (double-double) returns double value > double * int performed as double * double returns double value > double / int performed as double / double returns double value > > From ISO/IEC 9899:1999 (E): > "6.3.1.8 Usual arithmetic conversions > > 1 Many operators that expect operands of arithmetic type cause conversions > and yield result types in a similar way. The purpose is to determine a > common real type for the operands and result. For the specified operands, > each operand is converted, without change of type domain, to a type whose > corresponding real type is the common real type. Unless explicitly stated > otherwise, the common real type is also the corresponding real type of the > result, whose type domain is the type domain of the operands if they are the > same, and complex otherwise. This pattern is called the usual arithmetic > conversions: First, if the corresponding real type of either operand is long > double, the other operand is converted, without change of type domain, to a > type whose corresponding real type is long double. Otherwise, if the > corresponding real type of either operand is double, the other operand is > converted, without change of type domain, to a type whose corresponding real > type is double. Otherwise, if the corresponding real type of either operand > is float, the other operand is converted, without change of type domain, to > a type whose corresponding real type is float.51) Otherwise, the integer > promotions are performed on both operands. Then the following rules are > applied to the promoted operands: If both operands have the same type, then > no further conversion is needed. Otherwise, if both operands have signed > integer types or both have unsigned integer types, the operand with the type > of lesser integer conversion rank is converted to the type of the operand > with greater rank. Otherwise, if the operand that has unsigned integer type > has rank greater or equal to the rank of the type of the other operand, then > the operand with signed integer type is converted to the type of the operand > with unsigned integer type. Otherwise, if the type of the operand with > signed integer type can represent all of the values of the type of the > operand with unsigned integer type, then the operand with unsigned integer > type is converted to the type of the operand with signed integer type. > Otherwise, both operands are converted to the unsigned integer type > corresponding to the type of the operand with signed integer type. > 2 The values of floating operands and of the results of floating expressions > may be represented in greater precision and range than that required by the > type; the types are not changed thereby.52) > > Footnote 51) For example, addition of a double _Complex and a float entails > just the conversion of the float operand to double (and yields a double > _Complex result). > > Footnote 52) The cast and assignment operators are still required to perform > their specified conversions as described in 6.3.1.4 and 6.3.1.5." > > You can summarize the general idea of the promotions as "if an operation > takes place between wide and narrow, perform using wide and wide instead" But what stops the compiler to calculate the 5/9 first as it is a constant expression and can be done on compile time? AFAIK only guaranteed sequencing on expressions are: 1. precedence 2. comma operation 3. boolean operations || and && 4. ?: So an expression a*b/c can be calculated (a*b)/c or a*(b/c). Topi -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." - Bertrand Russell "How come he didn't put 'I think' at the end of it?" - Anonymous |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
Topi Linkala said:
<snip> > But what stops the compiler to calculate the 5/9 first as it is a > constant expression and can be done on compile time? If I am not mistaken, the statement under consideration is this: degC = (degF - 32) * 5 / 9; where degC and degF are doubles. The answer to your question is that multiplication and division have the same precedence and left-to-right associativity. Whilst it is true that 5 / 9 is a constant expression with value 0, that constant expression *does not appear* in the statement under consideration (despite appearances!). The precedence and associativity "rules" that apply here can be expressed in a different way, as the following parse tree shows: assign / \ degC div / \ mul 9 / \ sub 5 / \ degF 32 The rule for order of evaluation is simple: you can do stuff in any order you like, *provided* that the result is the same as if you'd fully evaluated both operands of an arithmetic operator to discover what value should be passed back up the tree. So you can do the division by 9 first if you like, but *only* if you can deduce correctly what the left-hand operand of the division should be. And let's face it, the simplest way to do that is to do the sub and mul first. > AFAIK only guaranteed sequencing on expressions are: > > 1. precedence You forgot associativity and sequence points. > 2. comma operation > 3. boolean operations || and && > 4. ?: These are special cases of sequence points. > So an expression a*b/c can be calculated (a*b)/c or a*(b/c). Wrong. Multiplication and division are associated left-to-right. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
Richard Heathfield wrote:
> Topi Linkala said: > > <snip> > >>But what stops the compiler to calculate the 5/9 first as it is a >>constant expression and can be done on compile time? > > > If I am not mistaken, the statement under consideration is this: > > degC = (degF - 32) * 5 / 9; > > where degC and degF are doubles. > > The answer to your question is that multiplication and division have the > same precedence and left-to-right associativity. Whilst it is true that > 5 / 9 is a constant expression with value 0, that constant expression *does > not appear* in the statement under consideration (despite appearances!). > > The precedence and associativity "rules" that apply here can be expressed > in a different way, as the following parse tree shows: > > assign > / \ > degC div > / \ > mul 9 > / \ > sub 5 > / \ > degF 32 > > The rule for order of evaluation is simple: you can do stuff in any order > you like, *provided* that the result is the same as if you'd fully > evaluated both operands of an arithmetic operator to discover what value > should be passed back up the tree. > > So you can do the division by 9 first if you like, but *only* if you can > deduce correctly what the left-hand operand of the division should be. And > let's face it, the simplest way to do that is to do the sub and mul first. > > >>AFAIK only guaranteed sequencing on expressions are: >> >>1. precedence > > > You forgot associativity and sequence points. > > >>2. comma operation >>3. boolean operations || and && >>4. ?: > > > These are special cases of sequence points. > > >>So an expression a*b/c can be calculated (a*b)/c or a*(b/c). > > > Wrong. Multiplication and division are associated left-to-right. > From whence? My K&R states in section 2.5 Arithmetic Operators: "The order of evaluation is not specified for associative and commutative operators like * and +; the compiler may rearrange a parenthesized computation involving onr of these. thus a+(b+c) can be evaluated as (a+b)+c. This rarely makes ant difference, but if particular order is required, explicite temporary variables must be used." Topi -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." - Bertrand Russell "How come he didn't put 'I think' at the end of it?" - Anonymous |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
Topi Linkala said:
> Richard Heathfield wrote: > >> Topi Linkala said: >> >> <snip> >> >>>But what stops the compiler to calculate the 5/9 first as it is a >>>constant expression and can be done on compile time? >> >> >> If I am not mistaken, the statement under consideration is this: >> >> degC = (degF - 32) * 5 / 9; >> >> where degC and degF are doubles. >> >> The answer to your question is that multiplication and division have the >> same precedence and left-to-right associativity. Whilst it is true that >> 5 / 9 is a constant expression with value 0, that constant expression >> *does not appear* in the statement under consideration (despite >> appearances!). >> >> The precedence and associativity "rules" that apply here can be >> expressed in a different way, as the following parse tree shows: >> >> assign >> / \ >> degC div >> / \ >> mul 9 >> / \ >> sub 5 >> / \ >> degF 32 >> >> The rule for order of evaluation is simple: you can do stuff in any >> order you like, *provided* that the result is the same as if you'd fully >> evaluated both operands of an arithmetic operator to discover what value >> should be passed back up the tree. >> >> So you can do the division by 9 first if you like, but *only* if you can >> deduce correctly what the left-hand operand of the division should be. >> And let's face it, the simplest way to do that is to do the sub and mul >> first. >> >> >>>AFAIK only guaranteed sequencing on expressions are: >>> >>>1. precedence >> >> >> You forgot associativity and sequence points. >> >> >>>2. comma operation >>>3. boolean operations || and && >>>4. ?: >> >> >> These are special cases of sequence points. >> >> >>>So an expression a*b/c can be calculated (a*b)/c or a*(b/c). >> >> >> Wrong. Multiplication and division are associated left-to-right. >> > > From whence? From the grammar. > My K&R states in section 2.5 Arithmetic Operators: > > "The order of evaluation is not specified for associative and > commutative operators like * and +; the compiler may rearrange a > parenthesized computation involving onr of these. thus a+(b+c) can be > evaluated as (a+b)+c. Note that, whilst multiplication is indeed commutative, and so is addition, that doesn't mean that multiplication and addition are co-commutative. When more than one operator is used, ordering normally matters a great deal, and the grammar reflects and enforces this. What's more, K&R's claim is not universally true even if restricted to multiple uses of a single operator - for example, an implementation is not free to evaluate x+(INT_MAX+INT_MIN) as (x+INT_MAX)+(INT_MIN) unless x happens to be 0. And now that you've got K&R2 out, check section 2.12 - Precedence and Order of Evaluation. Observe the precedence table on p53, and note the associativity column. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
Topi Linkala <nes@iki.fi> writes:
> >>So an expression a*b/c can be calculated (a*b)/c or a*(b/c). > > Wrong. Multiplication and division are associated left-to-right. > > > > From whence? My K&R states in section 2.5 Arithmetic Operators: > > "The order of evaluation is not specified for associative and commutative > operators like * and +; the compiler may rearrange a parenthesized > computation involving onr of these. thus a+(b+c) can be evaluated as > (a+b)+c. This rarely makes ant difference, but if particular order is > required, explicite temporary variables must be used." That's not in mine; is yours the first edition? Mine is the second one (with the ANSI C red stamp). And the standard is quite explicit that it isn't the case (see 5.1.2.3/3 and example 6 of the same paragraph). Yours, -- Jean-Marc |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
Topi Linkala <nes@iki.fi> wrote:
> > From whence? My K&R states in section 2.5 Arithmetic Operators: > > "The order of evaluation is not specified for associative and > commutative operators like * and +; the compiler may rearrange a > parenthesized computation involving onr of these. thus a+(b+c) can be > evaluated as (a+b)+c. This rarely makes ant difference, but if > particular order is required, explicite temporary variables must be used." That was changed by the original ANSI standard and no longer appears in K&R2. It was replaced by what's referred to as "the as-if rule", which basically says that the compiler can rearrange things however it wants as long as the answer is the same as if it had not been rearranged. That allows the above regrouping for integer operations as long as integer overflow is silent and reversible (which it is on most machines) but forbids it for machines where that is not true and for floating point. -Larry Jones I can feel my brain beginning to atrophy already. -- Calvin |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
Topi Linkala wrote:
> ... > But what stops the compiler to calculate the 5/9 first as it is a > constant expression and can be done on compile time? Nothing really. In the expresison 'E * 5/9' the compiler is free to calculate '5/9' in advance. What the compiler _cannot_ do is to destroy the semantics if the full expression (derived from the grammar) and evaluate '5/9' as an integral division. If the compiler want to pre-evaluate '5/9', it can do that, but it has to make sure that the result is precise enough so that the whole thing works "as if" it evaluated 'E * 5' first and then divided the result by '9'. > AFAIK only guaranteed sequencing on expressions are: > > 1. precedence Precedence does not guarantee any sequencing. If defines the semantics of the expression, i.e. it disambiguates the result. It tells you that '2 + 2 * 2' is 6 and not 8. But the compiler is perfectly free to forget about these 2's and obtain that final 6 as '37 / 5 + 1' if it is so inclined. > 2. comma operation > 3. boolean operations || and && > 4. ?: These three do indeed introduce real sequencing. > So an expression a*b/c can be calculated (a*b)/c or a*(b/c). Yes, it can be calculated as 'a*(b/c)' as long as the result is the same as '(a*b)/c'. If on the given platform 'a*(b/c)' give a different result, then it the compiler will have no choice but calculate it as '(a*b)/c'. -- Best regards, Andrey Tarasevich |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
Topi Linkala wrote:
>> ... >> Wrong. Multiplication and division are associated left-to-right. >> > > From whence? My K&R states in section 2.5 Arithmetic Operators: > > "The order of evaluation is not specified for associative and > commutative operators like * and +; the compiler may rearrange a > parenthesized computation involving onr of these. thus a+(b+c) can be > evaluated as (a+b)+c. This rarely makes ant difference, but if > particular order is required, explicite temporary variables must be used." You are continuing to mix to different and virtually unrelated concepts: associativity and order of evaluation. -- Best regards, Andrey Tarasevich |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
Richard Heathfield wrote:
> And now that you've got K&R2 out, check section 2.12 - Precedence and Order > of Evaluation. Observe the precedence table on p53, and note the > associativity column. Section 2.12 fourth paragraph: "As mentioned before, expressions involving one of the associative and commutative operators (*, +, &, ^, |) can be rearranbged even when parenthesized." Topi -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." - Bertrand Russell "How come he didn't put 'I think' at the end of it?" - Anonymous |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
Topi Linkala said:
> Richard Heathfield wrote: > >> And now that you've got K&R2 out, check section 2.12 - Precedence and >> Order of Evaluation. Observe the precedence table on p53, and note the >> associativity column. > > Section 2.12 fourth paragraph: > > "As mentioned before, expressions involving one of the associative and > commutative operators (*, +, &, ^, |) can be rearranbged even when > parenthesized." Note: "one of". A * B / C involves a division as well as a multiplication. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
Topi Linkala <nes@iki.fi> wrote:
> Richard Heathfield wrote: > >> And now that you've got K&R2 out, check section 2.12 - Precedence and Order >> of Evaluation. Observe the precedence table on p53, and note the >> associativity column. > > Section 2.12 fourth paragraph: > > "As mentioned before, expressions involving one of the associative and > commutative operators (*, +, &, ^, |) can be rearranbged even when > parenthesized." That's K&R. K&R2 (the Second Edition) does not contain that text. -Larry Jones Hey Doc, for 10 bucks I'll make sure you see those kids in the waiting room again real soon! -- Calvin |
|