2014-12-22 77 views
2

好了,所以我做了一些测试,以我的程序在这里:垃圾值返回总和C++

#include <iostream> 
#include <cstring> 
#include <windows.h> 
using namespace std; 

void calcTwinkieChange(); 

int main(){ 
     calcTwinkieChange(); 
     return 0; 
} 

void calcTwinkieChange(){ 
    const double tCost(3.50); 
    const char DL1[3] = "DL", DL2[3] = "Dl", DL3[3] = "dl", DL4[3] = "dL"; 
    const char QR1[3] = "QR", QR2[3] = "Qr", QR3[3] = "qr", QR4[3] = "qR"; 
    const char DM1[3] = "DM", DM2[3] = "Dm", DM3[3] = "dm", DM4[3] = "dM"; 
    const char NK1[3] = "NK", NK2[3] = "Nk", NK3[3] = "nk", NK4[3] = "nK"; 
    double totalMoney(0), totalChange(0); 
    char inTyp[3]; 
    while(totalMoney < tCost){ 
     system("CLS"); 
     cout << "Input \"DL\" for dollar, \"QR\" for quarter, \"DM\" for dimes, and \"NK\" for nickels:" << endl; 
     cin >> inTyp; 

     if(strncmp(inTyp, DL1, 3) == 0 || strncmp(inTyp, DL2, 3) == 0 || strncmp(inTyp, DL3, 3) == 0 || strncmp(inTyp, DL4, 3) == 0){ 
     totalMoney += 1.00; 
     cout << "Amount: $" << totalMoney << endl; 
     system("PAUSE"); 
     } 
     else if(strncmp(inTyp, QR1, 3) == 0 || strncmp(inTyp, QR2, 3) == 0 || strncmp(inTyp, QR3, 3) == 0 || strncmp(inTyp, QR4, 3) == 0){ 
     totalMoney += 0.25; 
     cout << "Amount: $" << totalMoney << endl; 
     system("PAUSE"); 
     } 
     else if(strncmp(inTyp, DM1, 3) == 0 || strncmp(inTyp, DM2, 3) == 0 || strncmp(inTyp, DM3, 3) == 0 || strncmp(inTyp, DM4, 3) == 0){ 
     totalMoney += 0.10; 
     cout << "Amount: $" << totalMoney << endl; 
     system("PAUSE"); 
     } 
     else if(strncmp(inTyp, NK1, 3) == 0 || strncmp(inTyp, NK2, 3) == 0 || strncmp(inTyp, NK3, 3) == 0 || strncmp(inTyp, NK4, 3) == 0){ 
     totalMoney += 0.05; 
     cout << "Amount: $" << totalMoney << endl; 
     system("PAUSE"); 
     } 
     else{ 
      Beep(1000, 300); 
       cout << "Invalid Input, Please Try Again..." << endl; 
       system("PAUSE"); 
     } 
    } 
    /* 
    cout << "Total Cost: " << tCost << " " << totalMoney << " " << totalChange << " "; 
    system("PAUSE"); 
    */ 
//--- I believe the issue resides on the line bellow. It may contain an uninitialized variable— somehow. --- 
    totalChange = (totalMoney - tCost); 
    cout << "Enjoy your deep fried Twinkie..." << endl; 
    cout << "Your change: $" << totalChange << endl; 
    system("PAUSE"); 
} 

该计划旨在采取块钱,宿舍,硬币和五分一前一后,等到的总和总计达到了3.50美元,其中该计划将返回“享受你的油炸Twinkie。”并在适用的情况下返回适量的更改。

程序的伟大工程,并返回改变正常,直到我进入了35次助攻,并得到这是我回报的变化:

enter image description here我也相信进入70个镍时发生同样的事情,并返回一个垃圾值。

任何洞察到我的问题的来源是非常感谢。 还应该提到的是,我的C++老师没有得到这个以太,所以我在这里。

+2

您应该阅读[每个计算机科学家应了解的浮点算术知识](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)。我意识到大多数计算机科学家不知道这些东西。即使他们在某个时候确实知道了这一点,但他们已经忘记了这一切。不过,它仍然是相关的。 –

+3

高级实体与我联系。您将通过使用称为*调试器*的神奇工具获得更多的见解。 –

+3

Neaderthal正在高呼。他们说要改用* print *语句;他们喜欢他们古老的方式。 –

回答

3

“e-015”是你的线索,“变化”本质上是$ 0,而这只是一个舍入误差。你的老师至少需要了解四舍五入错误!如果你有0.50美元或0.25美元,这可以完全用二进制表示,但0.05美元将是二进制的重复分数,并且不能准确地表示...... 00101's的无限重复序列将在48位或其它任何值后被截断是。所以这些镍币永远不会达到3.50美元。

解决方法是打印答案只有合理的小数位数,或代表美元而不是美元的所有东西。

BTW,我想大多数程序员宁愿这句法:

常量双tCost = 3.50;

而不是:

const double tCost(3.50);

+0

或'const double tCost {3.50};' –

2

而不是在double中使用美元金额,请使用int中的美分。这将消除在进行算术运算时不可避免地产生的舍入误差,尤其是重复的减法运算。

问题是计算机不能像人类一样使用小数点,它们以二进制方式工作。一个简单的小数如0.10不能完全用二进制表示,但会稍微偏离一点(0.10000000149011612)。当你处理很多这样的数字时,差异将会被放大。