# 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.