开发者

I have a floating-point overflow problem

Well, I'm a beginner, it's my year as a computer science major. I'm trying to do an exercise from my textbook that has me use a struct called MovieData that has a constructor that allows me to initialize the member variables when the MovieData struct is created. Here's what my code looks like:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

// struct called MovieData
struct MovieData
{
    string title;
    string director;
    unsigned year;
    unsigned running_time;
    double production_cost;
    double first_year_revenue;

    MovieData() // default constructor
    {
        title = "Title";
        director = "Director";
        year = 2009;
        running_time = 90;
        production_cost = 1000000.00;
        first_year_revenue = 1000000.00;
    }
    // Constructor with arguments:
    MovieData(string t, string d, unsigned y, unsigned r, double p, double f)
    {
        title = t;
        director = d;
        year = y;
        running_time = r;
    }
};

// function prototype:
void displayMovieData(MovieData);

// main:
int main()
{
    // declare variables:
    MovieData movie, terminator("Terminator", "James Cameron", 1984, 120, 5000000, 2000000);

    // calling displayMovieData function for movie and terminator
    // so it will display information about the movie:
    displayMovieData(movie);
    displayMovieData(terminator);

    return 0;
}

// displayMovieData function:
// It receives struct MovieData variable as
// an argument and displays that argument's
// movie information to the user.
void displayMovieData(MovieData m)
{
    cout << m.title << endl;
    cout << m.director << endl;
    cout << m.year << endl;
    cout << m.running_time << endl;
    cout << fixed << showpoint << setprecision(2);
    cout << m.production_cost << endl;
    cout << m.first_year_revenue << endl << endl;
}

here is the output I received:

Title
Director
2009
90
1000000.00
1000000.00

Terminator
James Cameron
1984
120
-92559631349317830000000000000000000000000000000000000000000000.00
-92559631349317830000000000000000000000000000000000000000000000.00

Press any key to continue . . .

Compiled on Microsoft Visual C++ 2008 Express Edition.

My question is, is this happening due to an overflow of the double data-type? I even tried it using long double and the same thing occurs. even though i used 5mil as production_cost and 2mil as first_year_revenue both numbers output are the same. Using my default constructor properly prints out 1000000. Am I using the correct data-type in this case? I want it to be double because it's a monetary number, dollars and cen开发者_JAVA技巧ts.

Thanks for whatever help comes my way. Sorry about my long question. It's my first post on SO, so any feedback on correct format of posting questions will be great, Thanks!


Thanks for posting your complete code, the problem is now obvious. The following function is the problem:

MovieData(string t, string d, unsigned y, unsigned r, double p, double f)
{
    title = t;
    director = d;
    year = y;
    running_time = r;
}

You have omitted the following statements:

    production_cost = p;
    first_year_revenue = f;

Without those statements, production_cost and first_year_revenue are not initialised when using the above constructor.

This exercise highlights the need to post the exact code you're using when posting questions on Stack Overflow. The first version of the code you posted was different, and did not contain this bug.


Fixing the mistakes that stopped the code from compiling (missing semicolons, uppercase M instead of lowercase m) I get the following:

#include <iostream>
#include <iomanip>

using namespace std;

struct MovieData
{
    string title;
    string director;
    unsigned year;
    unsigned running_time;
    double production_cost;
    double first_year_revenue;

    MovieData() // My default constructor
    {
        title = "Title";
        director = "Director";
        year = 2009;
        running_time = 90;
        production_cost = 1000000.00; // this one comes out ok.
        first_year_revenue = 1000000.00; // this one comes out ok as well.
    }
    // This is my constructor with arguments:
    MovieData(string t, string d, unsigned y, unsigned r, double p, double f)
    {
        title = t;
        director = d;
        year = y;
        running_time = r;
        production_cost = p;
        first_year_revenue = f;
    }
};

void displayMovieData(MovieData m)
{
    cout << m.title << endl;
    cout << m.director << endl;
    cout << m.year << endl;
    cout << m.running_time;
    cout << fixed << showpoint << setprecision(2);
    cout << m.production_cost << endl;
    cout << m.first_year_revenue << endl << endl;
}

int main()
{
  MovieData terminator(
    "Terminator", "James Cameron", 1984, 120, 5000000, 2000000);
  displayMovieData(terminator);
  return 0;
}

Compiling and running it does not reproduce your problem...:

$ g++ -Wall --pedantic z.cc
$ ./a.out
Terminator
James Cameron
1984
1205000000.00
2000000.00

$ 

Please copy and paste the code exactly as I gave it here and let us know what happens (and with what compiler, platform, etc etc -- I'm using gcc 4.0.1 on MacOSX 10.5).


No, you aren't going to overflow the range of a double with the revenues or production costs of any movie, ever.

My guess would be that the problem lies in your displayMovieData function. Can you post the code to that?
IIRC you can get weird values printed like that if you call something like printf and it gets confused between singles and doubles. Or if you pass it %d instead of %f...


Your output does not match the code you show - you omitted an '<< endl' after the running time that your output claims you included. That always makes our debugging harder.

Here is your code working correctly on MacOS X 10.5.8 (Leopard) with G++ 4.0.1.

#include <string>
using namespace std;

struct MovieData
{
    string title;
    string director;
    unsigned year;
    unsigned running_time;
    double production_cost;
    double first_year_revenue;

    MovieData() // My default constructor
    {
        title = "Title";
        director = "Director";
        year = 2009;
        running_time = 90;
        production_cost = 1000000.00; // this one comes out ok.
        first_year_revenue = 1000000.00; // this one comes out ok as well.
    }
    // This is my constructor with arguments:
    MovieData(string t, string d, unsigned y, unsigned r, double p, double f)
    {
        title = t;
        director = d;
        year = y;
        running_time = r;
        production_cost = p;
        first_year_revenue = f;
    }
};

#include <iostream>
#include <iomanip>
using namespace std;

void displayMovieData(MovieData m)
{
    cout << m.title << endl;
    cout << m.director << endl;
    cout << m.year << endl;
    cout << m.running_time << endl;
    cout << fixed << showpoint << setprecision(2);
    cout << m.production_cost << endl;
    cout << m.first_year_revenue << endl << endl;
}

int main()
{
    MovieData def;
    MovieData terminator("Terminator", "James Cameron", 1984, 120, 5000000, 2000000);
    MovieData terminator2("Terminator 2", "James Cameron", 1984, 120, 5000000.0, 2000000.0);
    displayMovieData(def);
    displayMovieData(terminator);
    displayMovieData(terminator2);
}

The output I get is:

Title
Director
2009
90
1000000.00
1000000.00

Terminator
James Cameron
1984
120
5000000.00
2000000.00

Terminator 2
James Cameron
1984
120
5000000.00
2000000.00

My best thesis (unsupported by the data above) is that somehow you have not got the conversion from 'int' to 'double' taking place in the calls to the constructor, but I confess I don't understand how that could happen.


Like the other answers here, I'm not certain what the problem might be, since the code appears to be okay. However, try replacing this declaration:

void displayMovieData(MovieData m)

with

void displayMovieData(const MovieData &m)

and see whether your situation improves. See the recent question Why is it preferable to write func( const Class &value )? for more information on the difference between these two declarations.

I should emphasise that this should not change the behaviour of your program, but if something about your compiler and/or runtime environment has a bug, the above code change may help isolate the problem.


I would try to add .0 to the number and make them doubles. It might be getting confused when trying to do the translation from integer to double.

This would mirror what you have in the default construtor which is working.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜