Carson Lloyd
Carson Lloyd

Reputation: 13

Why am I getting values of 1.#INF?

I have attached my code here.

I added a print statement for "tempval," and it is printing values of 1.#INF and -1.INF.

I looked it up, and found out that #INF is returned when dividing by 0, but I can't figure out why it would be doing that here.

Any suggestions?

/*
PROGRAM:    sinx.cpp
PURPOSE:    This program uses the infinite series for sin(x) and evaluates the value of the function sin(x)
            until the next term in the sum is less than 1E-6.
            It also compares the value calculated by the program using the infinite series to the value of sin(x)
            as determined by the pre-defined functions inside C++'s <cmath>.
*/

#include <iostream>
#include <ciso646>
#include <cmath>
#include <string>
#include <fstream>
using namespace std;

static int factorial(int);          //performs a factorial on the quantity passed, takes an int, returns an int
static string promptForString(string prompt);       //prompts the user for input, takes the input, and returns the input as a string (takes/returns string)
static void introduction();     //Runs promptForString, and depending on input answer, outputs instructions. (takes/returns string)

int main()
{
    //-------------------------------
    //----------EXPLANATION----------
    //-------------------------------
    cout << "-----" << endl;
    cout << "This program will calculate the value of sin(x), with your input of x," << endl;
    cout << "using the infinite series of sin(x), and will stop calculations" << endl;
    cout << "when the next term in the series is less that 1E-6." << endl << endl;
    introduction();

    //------------------------------
    //----------USER-INPUT----------
    //------------------------------
    double x;

    cout << "-----" << endl;
    cout << "Enter a value for x: ";        // User-input for the value to calculate the sin of
    cin >> x;
    cout << endl;

    //--------------------------------
    //----------CALCULATIONS----------
    //--------------------------------
    double sinx = 0;            //initialize sinx so it is available inside the loop
    bool done = false;
    while (done == false)
    {
        for (int i = 0; i >= 0; i++)        //While i>0 (infinite loop) --- ends due to conditions inside the loops
        {
            double tempval = (pow(-1, i))*( (pow(x, (2.0 * i) + 1.0)) / (factorial((2 * i) + 1)));  //term "i" calculation
            cout << tempval << endl;
            if (fabs(tempval) < (1 * (pow(10, -6))))                //if it is precise enough, end the loops
            {
                i = -2; //low enough so that it will add 1 ( i = -1 ) at the end of the loop, then fail to meet the correct for loop conditions
                done = true;
            }

            else if (fabs(tempval) >= (1 * (pow(10, -6))))          //if it is not precise enough yet, add the term in the series, and the loop will loop
            {
                sinx += tempval;
            }
        }
    }

    //At this point, the calculation for sin(x) with the series is done, and the value is stored in the double "sinx"

    //------------------------------
    //----------COMPARISON----------
    //------------------------------
    double cmathsinx = sin(x);                      //cmath's interpretation
    double difference = abs(cmathsinx - sinx);      //Difference between calculated and function values

    //--------------------------
    //----------OUTPUT----------
    //--------------------------

    cout << "-----" << endl;
    cout << "The program used the infinite series for sin(x) and" << endl
        << "calculated for sin(" << x << ")." << endl
        << "The value was: " << sinx << "." << endl << endl;

    cout << "The sin function in the math header file for C++ calculated" << endl
        << "that sin(" << x << ") = " << cmathsinx << "." << endl << endl;

    cout << "The difference between those two numbers is: " << difference << "."
        << endl << endl;

    cout << "-----" << endl << endl << endl;

    return 0;
}

static int factorial(int number)
{
    int temp;

    if (number <= 1)
    {
        return 1;
    }

    temp = number * factorial(number - 1);
    return temp;
    //return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}

static string promptForString(string prompt)
{
    cout << prompt;                         //prompts user for a string and returns the string to the main program
    string input;
    cin >> input;
    return input;
}

void introduction()
{
    string prompt = "-----\nDo you need instructions? Enter \"y\" for yes and \"n\" for no: ";
    string yesno = promptForString(prompt);

    string instructions = "\n Enter a value for x, and then press enter.";

    if (yesno == "y")
        cout << instructions << endl << endl;
    else if (yesno == "n")
        cout << "OK, here we go." << endl << endl;
}

EDIT: I ran a test with just the for loop and the tempval calculation. At the beginning, it returns correct values, but soon after, it begins returning +/- 1.#INF

Upvotes: 1

Views: 8886

Answers (1)

ganz
ganz

Reputation: 164

You're probably running into integer overflow issues. 13! exceeds the maximum value an int can hold (6,227,020,800 > 2,147,483,647), so your infinite series will return the wrong value when i >= 6.

Using a larger datatype (std::uint64_t) will help, but not by much -- 21! will exceed its limit as well, so you need to converge by the 10th iteration.

Upvotes: 2

Related Questions