1

I have the following code (printfs are for debugging)

float maximum = max(num1, max(num2, num3));
float other1 = min(num1, min(num2, num3));
float other2 = num1 + num2 + num3 - other1 - maximum;
//Now we know the maximum is maybe the hypothenuse

printf("Max %f, other %f, other %f\n", maximum, other1, other2);
printf("%f %f %f\n", pow(other1, 2), pow(other2, 2), pow(maximum, 2));
printf("%d\n", (pow(other1, 2) + pow(other2, 2)) == pow(maximum, 2));
return(pow(other1, 2) + pow(other2, 2) == pow(maximum, 2));

What I am trying to do is to check if 3 numbers are a pythagorean triple. Well, when entering the numbers 3, 4 and 5 it returns 0.

enter image description here

I have no idea why this behaviour happens. I'm pretty sure the problem is with the comparison, but I don't get what's wrong...

I would appreciate some help! Thanks!

Joseph Quinsey
  • 9,553
  • 10
  • 54
  • 77
Amit Gold
  • 727
  • 7
  • 22
  • 1
    Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example. – too honest for this site Dec 12 '15 at 16:26
  • 3
    `==` + `float`s -> evil. – cadaniluk Dec 12 '15 at 16:26
  • 3
    I thought the whole point of pythagorean triples were that they are *integral*. – Kerrek SB Dec 12 '15 at 16:34

3 Answers3

2

Assuming your math is correct the issue is with float comparison. Because floats and doubles do not produce "exact" results, simply using "==" comparison does not work.

Instead you need to do something like:

// if the difference between the two is very small they are basically equivalent
if fabs(a - b) < 0.00001

See this answer for more explanation of how to compare floats properly:

Comparing floating point numbers in C

Community
  • 1
  • 1
Justin Meiners
  • 10,754
  • 6
  • 50
  • 92
1

This might be overkill for your application, but if you don't mind using an open-sourced and stable library, GSL has a function called int gsl_fcmp (double x, double y, double epsilon) which compares two double precision floats to any desired epsilon (accuracy). This takes into account relative accuracy with an algorithm that's more robust than fabs(). It's great for testing your code as well.

Install gsl and link to library when compiling. With your other includes, add

#include <gsl/gsl_math.h>

Then your code would be

float maximum = max(num1, max(num2, num3));
float other1 = min(num1, min(num2, num3));
float other2 = num1 + num2 + num3 - other1 - maximum;
//Now we know the maximum is maybe the hypothenuse

printf("Max %f, other %f, other %f\n", maximum, other1, other2);
printf("%f %f %f\n", pow(other1, 2), pow(other2, 2), pow(maximum, 2));
int is_comparable = (0 == gsl_fcmp (pow(other1, 2) + pow(other2, 2), 
                                    pow(maximum, 2), 0.00001));
printf("%d\n", is_comparable);
return is_comparable;

Edit

I should add that GSL stands for GNU Scientific Library

ChisholmKyle
  • 449
  • 3
  • 10
-1

Quoting Eric Postpischil's answer to Why is my integer math with std::pow giving the wrong answer?:

All the other answers so far miss or dance around the one and only problem in the question: The pow in your C++ implementation is poor quality. It returns an inaccurate answer when there is no need to.

Get a better C++ implementation, or at least replace the math functions in it.

See also Pascal Cuoq's answer to std::pow with integer parameters, comparing to an integer type and http://blog.frama-c.com/index.php?post/2013/04/06/Non-experts-need-accurate-floating-point-the-most.

Community
  • 1
  • 1
Joseph Quinsey
  • 9,553
  • 10
  • 54
  • 77
  • That doesn't really help/address my question – Amit Gold Apr 27 '16 at 17:04
  • For what it is worth, the SO profiles for the writers quoted here, Eric Postpischil and Pascal Cuoq, state that they are, respectively, "senior software engineer in Apple’s Vector and Numerics Group" and "only owner of the floating-point gold badge that wasn't in the IEEE 754 standardization committee". – Joseph Quinsey Apr 27 '16 at 23:30