3

I have the following function to convert from radians to degrees:

float DegreesToRadians(float degrees) {
    return degrees * (PI / 180);
}

When I now do:

sinf(DegreesToRadians(90));

This returns 1, as expected. But when I do:

sinf(DegreesToRadians(180));

It returns -8.74228e-08. Does anybody know why this is happening? (This happens with cosf too, but in reverse: 180 -> -1; 90 -> -8.74228e-08)

Ams1901
  • 69
  • 1
  • 1
  • 6
  • 2
    You can't represent the correct value of `PI / 180` exactly. – Andy Turner Jul 25 '21 at 08:27
  • 1
    Type `float` has a limited precision. Try with `double`, you'll get something around e-16. – Bob__ Jul 25 '21 at 08:29
  • Further to Andy's comment, consider using the (usually defined) constant `M_PI`; – enhzflep Jul 25 '21 at 08:29
  • 2
    Aside from the specific issues with Pi, there is a general issue with floating point math, you should be aware of: [SO: Is floating point math broken?](https://stackoverflow.com/q/588004/7478597). There is a sub-discipline [Numerical analysis](https://en.wikipedia.org/wiki/Numerical_analysis) to deal with such issues. – Scheff's Cat Jul 25 '21 at 08:35
  • Specifically, concerning sin and cos, you may notice that the function graph has a low slope (around 0) in certain intervals and a higher (near 1 or -1) in others. Reverse computations in the intervals where it's close to 0 are usually not quite precise. This can be improved by clever substitutions, and sin and cos are nice example for this. (Where the slope of sin(x) is near 0, the slope of cos(x) is near 1 or -1 and vice versa.) – Scheff's Cat Jul 25 '21 at 08:39
  • Is there nothing in the Standard Library? – Sandburg Sep 14 '22 at 09:16

2 Answers2

5

How do I convert degrees to radians?

OP's degrees to radians conversion is reasonable.

return degrees * (PI / 180);

when I do: sinf(DegreesToRadians(180)); It returns -8.74228e-08.

This does not meet OP's expectations as degrees * (PI / 180) was not done exactly given PI is not π @Andy Turner. PI is machine pi, a nearby representable value of π. π is an irrational number. All finite floating point values are rational. There is no way to do non_zero_degrees * (π / 180) exactly. The error in the approximations are amplified in the sinf() call.

sinf(DegreesToRadians(180)) does not result in sine(π), but sine(PI). PI is close to π, but not the same. double graphical example.


Instead, reduce the range of of the angle in degrees first to maintain accuracy with trigonometric identities.

Example

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
4

Well, your PI is an approximation of the real mathematical constant. Then your degree-to-radian conversion is an approximation of the real conversion because floating point math is an approximation. And then, the standard sinf function approximates the sin function in math. Thus, you should expect your results to be approximate. -8.74228e-08 is a number close to 0. It's an approximation.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93