455,512 Members | 1,830 Online Need help? Post your question and get tips & solutions from a community of 455,512 IT Pros & Developers. It's quick & easy.

# Calculations inline with conditionals

 P: n/a 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. Oct 28 '05 #1
3 Replies

 P: n/a 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 in your compilers documentation. -- Karl Heinz Buchegger kb******@gascad.at Oct 28 '05 #2

 P: n/a 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 Oct 28 '05 #3

 P: n/a 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 Oct 28 '05 #4

### This discussion thread is closed

Replies have been disabled for this discussion. 