Velocity Reviews > C++ > Calculations inline with conditionals

# Calculations inline with conditionals

jdwyer3
Guest
Posts: n/a

 10-28-2005
I'm using Visual C++.Net 2003, and I have noticed a little quirkiness
when using a conditional based on the comparison of two calculations
that are performed inline with the conditional.

For example, if I run this code:

double angle1;
double angle2;

angle1 = 45;
angle2 = 45;

if( tan( angle1 ) < tan( angle2 ) )
cout << "Angle 1";
else
cout << "Angle 2";

I would expect the conditional to return false and the output to be
"Angle 2". What actually happens, however, is that the output is
"Angle 1".

If, instead, I write the code so as to perform the calculation prior to
the conditional like so:

double angle1;
double angle2;
double temp1;
double temp2;

angle1 = 45;
angle2 = 45;

temp1 = tan( angle1 );
temp2 = tan( angle2 );

if( temp1 < temp2 )
cout << "Angle 1";
else
cout << "Angle 2";

the code runs as I would expect and the output is "Angle 2".

Can somebody explain what I am missing? What is the difference in the
way the two snippets work that would cause what I believe to be two
functionally identical pieces of code to operate differently.

Karl Heinz Buchegger
Guest
Posts: n/a

 10-28-2005
jdwyer3 wrote:
> I'm using Visual C++.Net 2003

[snip]
> Can somebody explain what I am missing?

Look up the /Op (Improve Float consistency) option

--
Karl Heinz Buchegger
http://www.velocityreviews.com/forums/(E-Mail Removed)

John Ratliff
Guest
Posts: n/a

 10-28-2005
jdwyer3 wrote:
> I'm using Visual C++.Net 2003, and I have noticed a little quirkiness
> when using a conditional based on the comparison of two calculations
> that are performed inline with the conditional.
>

http://www.parashift.com/c++-faq-lit...html#faq-29.17

--John Ratliff

Kai-Uwe Bux
Guest
Posts: n/a

 10-28-2005
John Ratliff wrote:

> jdwyer3 wrote:
>> I'm using Visual C++.Net 2003, and I have noticed a little quirkiness
>> when using a conditional based on the comparison of two calculations
>> that are performed inline with the conditional.
>>

>
> http://www.parashift.com/c++-faq-lit...html#faq-29.17

If I was running into the problem of the OP, reading that FAQ item would not
give me piece of mind. Have a closer look at the code under consideration:

double angle1;
double angle2;

angle1 = 45;
angle2 = 45;

if( tan( angle1 ) < tan( angle2 ) )
cout << "Angle 1";
else
cout << "Angle 2";

If the program prints Angle 1, it takes license to evaluate tan(45)
inconsistently. Note that after initialization angle1 == angle2 is
guaranteed by the standard. Yet the OP finds tan(angle1) != tan(angle2).

Now, look at the code from the FAQ:

double x = 1.0 / 10.0;
double y = x * 10.0;
if (y != 1.0)
std::cout << "surprise: " << y << " != 1\n";

Well, it is unreasonable to expect to different floating point calculations
to yield identical results just because they happen to be mathematically
equivalent -- unreasonable at least once one considers how real numbers are
represented in the computer. However, it is reasonable to expect a function
call to tan() to return identical values for identical arguments: this is
comparing the results from performing the same calculation two times.

I agree that the standard does no guarantee the natural behavior of math
functions (in fact it does not guarantee anything meaningful). Also, there
are good reasons why one might not want to make any stronger guarantees
here: The compiler can inline the function call and do optimizations that
take into account the callers context. For floating point arithmetic, we
might want to allow for those optimizations to slightly change the results.
However, that issue is not addressed in the FAQ. Maybe one should add this
case to the list of warnings:

Double-check your assumptions, including "obvious" things like how to
compute averages, how to solve quadratic equations, etc., etc. Do not
assume the formulas you learned in High School will work with floating
point numbers!

to include "obvious things like two calls to tan(45.0) will evaluate to
equal results."

Best

Kai-Uwe Bux