Reputation: 77
I tried searching for the answer to this question but to no avail. What I am trying to do is count the 0s of cos(x) between 0 and a number provided by a user in radians. I'm new to c++, so be gentle if this is trivial.
This is an excerpt from my code, (also note I'm not exactly sure about the difference between #import
and #include
, but I digress).
#define _USE_MATH_DEFINES
#import <iostream>
#import <algorithm>
#include <math.h>
#include <stdio.h>
int count = 0;
if (r > 0) {
for (float i = 0; i < r; i += M_PI_2) {
printf("\n\n%s: %f: %f\n\n", cos(i) == -float(0) ? "true":"false", \
cos(i), -float(0));
if (cos(i) == float(0) || cos(i) == -0) {
count++;
printf("Count: %d", count);
}
}
Using the value 2R as r, I should get the count to increase once but the if statement evaluates to false. I'm not sure I should be casting float to zero, nor checking against -0. Anyway this is the output to the print statements in this snippet of code.
It looks like cos(M_PI_2)
in fact equals -float(0)
so why does cos(M_PI_2) == -float(0)
evaluate to false
?? Again I just started to pick up c++ days ago, so my apologies if this is trivial.
Upvotes: 1
Views: 370
Reputation: 64904
It was not printed accurately enough to show it's different than zero.
Note that the result really shouldn't be zero in the first place, so that's not what the problem is. pi/2 is clearly not a rational number, so definitely not representable as a floating point number (in any integer base, also including binary). The cosine of a number x
close to pi/2 is roughly pi/2 - x
, so the magnitude of the cosine of the nearest float to pi/2 would be roughly the magnitude of the difference between that float and the actual value of pi/2. Since pi/2 is a fairly large number (compared to all the floating point numbers smaller than it), that difference can be approximated (it is of course again not a rational number) without flushing it to zero.
Upvotes: 4
Reputation: 57784
This one side of the double-edged sword of floating point. Do not compare floating point values for equality or inequality. Instead, bracket the range of values for approximate matches:
abs(cos(i) - float(0)) <= 0.0001 ? "true":"false"
Upvotes: 5