Why does the compiler do this?

1. Sep 17, 2014

Zondrina

1. The problem statement, all variables and given/known data

2. Relevant equations

3. The attempt at a solution

Here's some simple code that computes values of $\sin(x)$ and $\cos(x)$ using their Taylor expansions. After six terms, the approximation exceeds the computer's ability to represent it:

Code (Text):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

long double sinxSeries(int, double);
long double cosxSeries(int, double);

int factorial(int);

int main(){
printf("sin(pi/2) = %Lf \n",sinxSeries(6, M_PI/2));
printf("cos(pi/2) = %Lf \n",cosxSeries(6, M_PI/2));
return 0;
}

long double sinxSeries(int n, double x) {
long double returnSum = 0;

for(int i=0;i<n;i++)
returnSum += pow(-1,i) * (pow(x, 2*i + 1))/(factorial(2*i + 1));

return returnSum;
}

long double cosxSeries(int n, double x) {
long double returnSum = 0;

for(int i=0;i<n;i++)
returnSum += pow(-1,i) * (pow(x, 2*i))/(factorial(2*i));

return returnSum;
}

int factorial(int n) {
return(n <= 1 ? 1 : n*factorial(n-1));
}
This code produces the following output (note one of the outputs is horrendous):

Code (Text):
sin(pi/2) = 1.000000
cos(pi/2) = -0.000000
Program ended with exit code: 0
Negative zero?

When I change this line:

Code (Text):
printf("cos(pi/2) = %Lf \n",cosxSeries(6, M_PI/2));
To this:

Code (Text):
printf("cos(pi/2) = %Lf \n",cosxSeries(7, M_PI/2));
I get positive zero:

Code (Text):
sin(pi/2) = 1.000000
cos(pi/2) = 0.000000
Program ended with exit code: 0
What happened here exactly?

Last edited: Sep 17, 2014
2. Sep 17, 2014

AlephZero

I don't think you are getting exact positive and negative zeros here. Change the %Lf format to %Le, so you see what floating point values you are really calculating.

All calculation with float and double values are potentially inexact.

3. Sep 17, 2014

Zondrina

I found some justification: http://en.wikipedia.org/wiki/Signed_zero

The value will never be completely accurate due to truncation and round off.

4. Sep 17, 2014

willem2

That integer factorial function is going to overflow as well. 13! doesn't fit in a 32 bit integer.

A more efficient way of calculating this is to compute the next term from the taylor polynomial from the previous.

You can more easily compute (-x^(n+2)) / (n+2)! from (x^n) / n! than from scratch.

Even better is http://mathworld.wolfram.com/HornersRule.html

5. Sep 18, 2014

AlephZero

I suggest you stop trying to justify your statement about signed zeros with irrelevant links to wikipedia, and change the print format as I suggested.

The basic rule of debugging any computer software is to find out what the code actually does, not what you think it ought to do.

6. Sep 18, 2014

Zondrina

Yeah, i did that a long time ago. I already get it, like yesterday.

You don't seem to "get" my concern, but your hint to change the modifier was fine; even if it wasn't the point. It provided a visual, but not the answer. I was trying to understand the signed zero concept.

Thanks anyway.

7. Sep 18, 2014

D H

Staff Emeritus
AlephZero's hint was exactly to the point. Much of what you wrote in your opening post is incorrect. AlephZero was trying to point you toward a better understanding of the code that you wrote.

Your code does not exhibit the signed zero concept. It exhibits what happens to a number that is non-zero that prints as zero because of the output option you chose to use.