views:

258

answers:

6

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

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!

+2  A: 

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

Peter
[IEEE754 "Double"](http://en.wikipedia.org/wiki/Binary64) -- good for a high limit of ~1.79x(10^308) -- within a decreasing precision of course
pst
Yep. Even Waterworld didn't cost that much :)
Peter
Maybe in Zimbabwean dollars...
Greg Hewgill
I didn't know the details, I just put in numbers. Maybe the the movie didn't cost that much to make, but just to satisfy my curiosity I'd like to know how I could be able to put large sums as floating point for my own education, and in case I ever encounter something like this again.
blakejc70
I don't have a problem with the numbers you put in. I just don't think overflow is the problem here - as pst mentioned, the max value of a double is enormous.
Peter
+3  A: 

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

Alex Martelli
Maybe add the missing `endl` for clarity.
Greg Hewgill
That's two Mac's that come up with the same answer :)
Jonathan Leffler
Added all the code as I compiled it. Sorry about that!
blakejc70
+1  A: 

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.

Greg Hewgill
I tried your suggestion, and it made no difference. Thanks for the tidbit.
blakejc70
+1  A: 

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.

Jonathan Leffler
I added all the code as one block this time, and the results as a whole.
blakejc70
+9  A: 

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.

Greg Hewgill
Oh wow, thanks. I feel very small after that mistake. I looked at it and looked at it and it was right in front of me but I did not see it. Thanks for the help!
blakejc70
A: 

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.

Glenn