2014-12-22 75 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)。當你處理很多這樣的數字時,差異將會被放大。