NotMe
NotMe

Reputation: 77

Why does cos(M_PI_2) == float(0) evaluate to false? c++

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.

terminal snippet

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

Answers (2)

user555045
user555045

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

wallyk
wallyk

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

Related Questions