PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.c > Question on the FAQ
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Question on the FAQ

Réponse
 
LinkBack Outils de la discussion
Vieux 13/04/2008, 20h33   #1
Topi Linkala
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Question on the FAQ

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
  Réponse avec citation
Vieux 13/04/2008, 20h41   #2
Robert Gamble
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 13/04/2008, 20h48   #3
Topi Linkala
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 13/04/2008, 21h10   #4
Robert Gamble
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 13/04/2008, 21h33   #5
Flash Gordon
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 13/04/2008, 21h35   #6
Joe Wright
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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 ---
  Réponse avec citation
Vieux 13/04/2008, 21h53   #7
Topi Linkala
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 13/04/2008, 22h00   #8
Robert Gamble
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 14/04/2008, 00h23   #9
Andrey Tarasevich
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 14/04/2008, 05h25   #10
CBFalconer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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 **
  Réponse avec citation
Vieux 14/04/2008, 05h41   #11
Ian Collins
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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.
  Réponse avec citation
Vieux 15/04/2008, 01h52   #12
Dann Corbit
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

"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 **
  Réponse avec citation
Vieux 15/04/2008, 09h01   #13
Topi Linkala
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 15/04/2008, 09h20   #14
Richard Heathfield
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 15/04/2008, 09h40   #15
Topi Linkala
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 15/04/2008, 10h04   #16
Richard Heathfield
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 15/04/2008, 10h35   #17
Jean-Marc Bourguet
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 15/04/2008, 16h55   #18
lawrence.jones@siemens.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 15/04/2008, 19h41   #19
Andrey Tarasevich
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 15/04/2008, 19h43   #20
Andrey Tarasevich
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 16/04/2008, 10h06   #21
Topi Linkala
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 16/04/2008, 10h39   #22
Richard Heathfield
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Vieux 16/04/2008, 21h27   #23
lawrence.jones@siemens.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Question on the FAQ

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
  Réponse avec citation
Réponse

«