简体   繁体   English

我有一个浮点溢出问题

[英]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. 我正在尝试从我的教科书中进行练习,我使用一个名为MovieData的结构,它有一个构造函数,允许我在创建MovieData结构时初始化成员变量。 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. 在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. 我甚至尝试使用long double,同样的事情发生。 even though i used 5mil as production_cost and 2mil as first_year_revenue both numbers output are the same. 即使我使用5mil作为production_cost而使用2mil作为first_year_revenue两个数字输出都是相同的。 Using my default constructor properly prints out 1000000. Am I using the correct data-type in this case? 使用我的默认构造函数正确打印出1000000.在这种情况下我使用正确的数据类型吗? 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! 这是我关于SO的第一篇文章,所以关于发布问题的正确格式的任何反馈都会很棒,谢谢!

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. 如果没有这些语句,则在使用上述构造函数时不会初始化production_costfirst_year_revenue

This exercise highlights the need to post the exact code you're using when posting questions on Stack Overflow. 此练习强调了在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: 修复阻止代码编译的错误(缺少分号,大写M而不是小写m)我得到以下内容:

#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). 请完全按照我在此处给出的代码复制并粘贴代码,让我们知道会发生什么(以及使用什么编译器,平台等等 - 我在MacOSX 10.5上使用gcc 4.0.1)。

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. 我的猜测是问题在于你的displayMovieData函数。 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. 如果你打电话给像printf这样的东西,你可以得到像这样打印的奇怪值,并且它会在单打和双打之间混淆。 Or if you pass it %d instead of %f ... 或者如果你传递%d而不是%f ...

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 )? 查看最近的问题为什么写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. 我要强调,这应该改变你的程序的行为,但如果一些关于你的编译器和/或运行环境有一个错误,上面的代码改变可能有助于隔离问题。

Your output does not match the code you show - you omitted an '<< endl' after the running time that your output claims you included. 您的输出与您显示的代码不匹配 - 您在输出声明包含的运行时间后省略了“<< endl”。 That always makes our debugging harder. 这总是让我们的调试变得更难。

Here is your code working correctly on MacOS X 10.5.8 (Leopard) with G++ 4.0.1. 以下是使用G ++ 4.0.1在MacOS X 10.5.8(Leopard)上正常运行的代码。

#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. 我最好的论文(上面的数据不支持)是你在构造函数的调用中没有从'int'到'double'的转换,但我承认我不明白这是怎么回事。

I would try to add .0 to the number and make them doubles. 我会尝试将.0添加到数字并使它们成为双打。 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. 这将反映您在默认构造器中的工作情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM