2016-07-05 5 views
0

Ich habe ein C++ - Programm geschrieben (soll ein Geldzähler sein), ich habe einige Probleme mit meinem Code, ich brauche die Dezimalstellen zu zeigen. Ich verwende cout anstelle von printf, wenn das wichtig ist.Dezimalzahlen, die nicht im Geldzähler in C++ angezeigt werden

#include <iostream> 
#include <string> 
#include <cmath> 

using namespace std; 

int main() { 
    // Strings and Integers 
    int dollars; 
    int pennies; 
    int nickles; 
    int quarters; 
    int halfDollars; 
    int dimes; 
    int fiveBill; 
    int tenBill; 
    int twentyBill; 
    int fiftyBill; 
    int hundredBill; 

    // Coin/Bill Amounts 
    int penny = 0.01; 
    int dollar = 1.00; 
    int nickle = 0.05; 
    int quarter = 0.25; 
    int halfDollar = 0.50; 
    int dime = 0.10; 
    int five = 5.00; 
    int ten = 10.00; 
    int twenty = 20.00; 
    int fifty = 50.00; 
    int hundred = 100.00; 

    // Enter Amount 
    cout << "Count your money!\n\n" << endl << "Hundred Dollar Bills: "; 
    cin >> hundredBill; 
    cout << "\nFifty Dollar Bills: "; 
    cin >> fiftyBill; 
    cout << "\nTwenty Dollar Bills: "; 
    cin >> twentyBill; 
    cout << "\nTen Dollar Bills: "; 
    cin >> tenBill; 
    cout << "\nFive Dollar Bills: "; 
    cin >> fiveBill; 
    cout << "\nOne Dollar Bills: "; 
    cin >> dollars; 
    cout << "\nHalf-Dollars: "; 
    cin >> halfDollars; 
    cout << "\nQuaters: "; 
    cin >> quarters; 
    cout << "\nDimes: "; 
    cin >> dimes; 
    cout << "\nNickles: "; 
    cin >> nickles; 
    cout << "\nPennies: "; 
    cin >> pennies; 

    // Add Together 
    cout << (hundred * hundredBill) + (fifty * fiftyBill) + (twenty * twentyBill) + (ten * tenBill) + (five * fiveBill) + (dollars * dollar) + (halfDollar * halfDollars) + (quarter * quarters) + (dime * dimes) + (nickle *  nickles) + (penny * pennies); 
    system("PAUSE"); 

    return 0; 
} 
+1

Ganzzahlen haben keine Dezimalstellen. – tkausl

Antwort

2

Ihr Problem:

int penny = 0.01; 

penny ist ein int, ist der Name eine Abkürzung für 'Integralwert'. 0,01 ist vom Typ double. Wenn Sie einer beliebigen Form von int (int, long int, short int, ...) ein double (entweder als Literal oder von einer anderen Variablen) zuweisen, wird nur der ganzzahlige Teil zugewiesen und die Dezimalstellen werden verworfen (einfach gelöscht, keine Rundung) tritt auf - egal wie nah der Wert zum nächstgrößeren Integral ist.

So penny hält eigentlich nur 0. unter gleichen Bedingungen die anderen Variablen, dollar 1, nickle wieder 0, ...

Sie haben nun zwei Möglichkeiten. Entweder, konvertieren Sie alle Zahlen zu verdoppeln, oder doch einen kleinen Trick, indem alle Werte in Cent zuweisen:

int penny = 1; 
int dollar = 100; 

Dies ist, was würde ich es vorziehen. Nur dann, wenn es um die Ausgabe Ihnen entsprechende Formatierung tun würde:

printf("the value of my variable is %d.%.2d $\n", value/100, value % 100); 

Edit:

Wie viele bevorzugen die Ausgabe über std :: cout und dies wird eher ein Streit, eine Möglichkeit, es bequem zu tun wäre die folgende:

class Formatter 
{ 
    int value; 
    friend std::ostream& operator<<(std::ostream& s, Formatter f); 
public: 
    Formatter(int value) 
      : value(value) 
    { 
    } 
}; 
typedef Formatter F, M; 

std::ostream& operator<<(std::ostream& s, Formatter f) 
{ 
    char c = s.fill(); 
    return s << f.value/100 << '.' 
     << std::setfill('0') << std::setw(2) << f.value % 100 
     << std::setfill(c); // restore previous fill character! 
} 

Typedef nicht notwendig ist, natürlich, nur andere Namen zu illustrieren – irgendeine wählen, die für Sie am besten geeignet erscheint (F: Formatter, M: Geld, D: Dollar, .. .). Verbrauch dann:

std::cout << F(penny) << std::endl; 
+0

Smart-Lösung tatsächlich, außer der Stream kann sich für weitere Ausgaben falsch verhalten. –

+1

@PaulStelian Danke für den Hinweis - während die Auswirkungen von setw durch den nächsten Operator zurückgesetzt << (siehe [hier] (http://en.cppreference.com/w/cpp/io/manip/setw)), I darauf geachtet, dass die von Setfill nicht ... Edited entsprechend bearbeitet. – Aconcagua

0

I "cout" anstelle von "printf" verwenden, wenn es ankommt.

Nein, es ist egal mit welcher Ausgabe Sie erwartet haben.

Verwenden Sie alle Variablen, die Sie bearbeiten möchten w.r.t. Dezimalstellen als Datentyp 'Double'.

+2

'printf' verursacht in vielen Fällen viel weniger Aufwand, vergleiche' "% .2d", value' zu ​​'<< setw (2) << setfill ('0') << value'. Das ist wahrscheinlich der Grund, warum es in C++ noch lebt (und sehr lebendig ist ...). Zugegeben, cout hat einen großen Vorteil, wenn man mit Typedefs arbeitet, bei denen man den genauen Typ nicht kennt - oder letzteres könnte sich ändern ... – Aconcagua

+0

@Aconcagua stimme völlig zu! –

1

Wie gesagt, das Problem besteht darin, dass Sie versuchen, einer Integer-Variablen einen Dezimalwert zuzuweisen.

Was passiert, ist, dass Ihre Eingabe (im Falle von Dezimalwerten) entweder als double oder als float-Typ-Variable vom Compiler interpretiert werden kann. Bei der Zuweisung der gegebenen Eingabe kann int oder voll, eine ganze Zahl, nur einen Wert ohne eine Bruchkomponente enthalten. Der Compiler nimmt das zur Kenntnis und schränkt Ihre Eingabe auf einen Wert ein, den die Variable int haben kann. Der Compiler ist an nichts nach dem Dezimalpunkt interessiert und verwirft einfach den Rest.So

,

int a = 3.5 // int can't hold the decimal 0.5, narrows into 3 
int b = 3 // int can hold this, no narrowing 
double d = 3.5 // double can hold this, no narrowing 
float f = 3.5 // float can hold this, no narrowing 

Eine gute Möglichkeit wäre alle Variablen Ihre ganze Zahl mit dem Typ double zu ersetzen. In diesem einfachen Programm sollten Sie nicht die Notwendigkeit haben, printf zu verwenden, um die Eingabe zu formatieren. Wenn Sie sich fragen, warum sollte ich double statt float verwenden möchten. Hier

ist einige zusätzliche Informationen:

https://softwareengineering.stackexchange.com/questions/188721/when-do-you-use-float-and-when-do-you-use-double

Should I use double or float?

+0

Während ich die Verwendung von Double als eine Alternative vorschlug, gibt es auch einige Nachteile: Fließkomma-Arithmetik ist teurer, es gibt Probleme mit Runden, Gleichheitsvergleich muss als abs (Differenz) Aconcagua

+0

Das ist in der Tat der Fall, und ich stimme Ihnen vollkommen zu. Ich glaube jedoch, dass wir uns im Falle eines einfachen Programms wie diesem nicht mit den Leistungsproblemen der Fließkomma-Arithmetik befassen sollten. – Mithraell

+0

Sicher, Leistung ist nur ein Nebeneffekt und sollte nicht für die Entscheidung berücksichtigt werden. Aber du magst das vielleicht: 'double penny = 0.01; doppelter Nickel = 0,05; std :: cout << (2 * Penny + 3 * Penny == Nickel) << std :: endl; '. In solch einfachen Programmen würde ich lieber Operator == ... verwenden können. – Aconcagua

1

Wenn Sie möchten, ganze Zahlen zu halten, werfen das Ergebnis in einen float oder double. Stellen Sie dann die Genauigkeit auf 2 Stellen und festes Format ein.

#include <iostream> 
#include <iomanip> 

... 

float total = (float) ((hundred * hundredBill) + (fifty * fiftyBill) + (twenty * twentyBill) + (ten * tenBill) + (five * fiveBill) + (dollars * dollar) + (halfDollar * halfDollars) + (quarter * quarters) + (dime * dimes) + (nickle * nickles) + (penny * pennies)); 
cout << std::setprecision(2) << std::fixed << total << endl; 
+1

Guter Hinweis auf Formatierung (Genauigkeit, behoben). Das ist es, was die anderen "Fließkomma" Antworten bisher vermisst haben ... – Aconcagua

Verwandte Themen