There are two issues here, and the answer to neither of them is that you want to try to somehow avoid doing any rounding. In fact, you're probably going to need to do some well-chosen rounding.
The first issue is that no finite-precision floating-point representation can represent every fraction exactly. It's especially true that it's impossible to represent irrational numbers like sqrt(233)
exactly.
You tried to test your program on a triangle with sides 8, 13, and the square root of 233. Mathematically, that's a perfect right triangle, but it's impossible to ask your program to test that right triangle, because you literally can't say "the square root of 233" when you ask it. You certainly can't say 155.26. You can try 15.26434, but that's inaccurate, as is 15.264337522473748, or 15.2643375224737480252559487. No finite representation is ever going to be perfectly accurate.
And then the second problem is that the inherent imprecision in the representation of most fractions means that you're rarely going to find that, say, x*x + y*y
is exactly equal to z*z
. This is an example of a comparison for floating-point equality that you probably don't want to try to make. (You will often hear it said that you should "never compare floating-point numbers for equality", which is not too bad as a rule of thumb, but there's a lot more to be said.)
You tried updating your comparison code to
if(x*x + y*y - z*z > 0.999 && x*x + y*y - z*z < 1 || … )
but that's not quite right, either. If the quantities x*x + y*y
and z*z
are almost equal, their difference will be close to 0, although it could end up on either side. So what you were trying to do is more like
if(x*x + y*y - z*z > -.001 && x*x + y*y - z*z < 0.001 || … )
and this might actually work, to a point. You could simplify it (avoid the repeated subexpression) by writing
if(fabs(x*x + y*y - z*z) < 0.001 || … )
Using a fixed accuracy threshold like 0.001
like this doesn't work particularly well, however. Some better, relative approaches can be found in this question's other answers, or in question 14.5 in the C FAQ list.
Also, as another rule of thumb, you should almost never use type float
. You should almost always use type double
, which has roughly twice the precision, and will tend to give you far fewer headaches.