Why Does the Compiler Print Negative Zero in This C Program?

  • Thread starter Thread starter STEMucator
  • Start date Start date
  • Tags Tags
    Compiler
Click For Summary

Discussion Overview

The discussion revolves around the output of a C program that computes the sine and cosine of π/2 using Taylor series expansions. Participants explore the occurrence of negative zero in the output and the implications of floating-point representation in programming.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant notes that the program outputs negative zero for cos(π/2) when using six terms in the Taylor series, while changing to seven terms results in positive zero.
  • Another participant suggests changing the output format from %Lf to %Le to better visualize the floating-point values being calculated, emphasizing the inexact nature of float and double calculations.
  • A different participant raises concerns about the integer factorial function potentially overflowing for larger values, suggesting a more efficient calculation method for the Taylor series terms.
  • Some participants express disagreement regarding the relevance of external links to signed zero, with one asserting that the focus should be on understanding the code's behavior rather than theoretical justifications.
  • One participant argues that the original poster's code does not demonstrate the signed zero concept but rather shows how a non-zero number can print as zero due to the chosen output format.

Areas of Agreement / Disagreement

There is no consensus on the interpretation of the negative zero output or the relevance of signed zero in this context. Participants present differing views on debugging approaches and the significance of floating-point representation.

Contextual Notes

Participants discuss limitations related to floating-point precision and the potential for overflow in factorial calculations, but these issues remain unresolved within the conversation.

STEMucator
Homework Helper
Messages
2,076
Reaction score
140

Homework Statement



This is not really a homework problem, but something is just so far off about this I had to ask. Note this is written in C.

Homework Equations


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:
#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:
sin(pi/2) = 1.000000 
cos(pi/2) = -0.000000 
Program ended with exit code: 0

Negative zero?

When I change this line:

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

To this:

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

I get positive zero:

Code:
sin(pi/2) = 1.000000 
cos(pi/2) = 0.000000 
Program ended with exit code: 0

What happened here exactly?
 
Last edited:
Physics news on Phys.org
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.
 
AlephZero said:
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.

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

The value will never be completely accurate due to truncation and round off.
 
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
 
Zondrina said:
I found some justification: http://en.wikipedia.org/wiki/Signed_zero
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.
 
AlephZero said:
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.
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.
 
Zondrina said:
You don't seem to "get" my concern, but your hint to change the modifier was fine; even if it wasn't the point.
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.


I was trying to understand the signed zero concept.
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.
 

Similar threads

  • · Replies 19 ·
Replies
19
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 12 ·
Replies
12
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 17 ·
Replies
17
Views
3K