www.vorkurse.de
Ein Projekt von vorhilfe.de
Die Online-Kurse der Vorhilfe

E-Learning leicht gemacht.
Hallo Gast!einloggen | registrieren ]
Startseite · Mitglieder · Teams · Forum · Wissen · Kurse · Impressum
Forenbaum
^ Forenbaum
Status Mathe-Vorkurse
  Status Organisatorisches
  Status Schule
    Status Wiederholung Algebra
    Status Einführung Analysis
    Status Einführung Analytisc
    Status VK 21: Mathematik 6.
    Status VK 37: Kurvendiskussionen
    Status VK Abivorbereitungen
  Status Universität
    Status Lerngruppe LinAlg
    Status VK 13 Analysis I FH
    Status Algebra 2006
    Status VK 22: Algebra 2007
    Status GruMiHH 06
    Status VK 58: Algebra 1
    Status VK 59: Lineare Algebra
    Status VK 60: Analysis
    Status Wahrscheinlichkeitst

Gezeigt werden alle Foren bis zur Tiefe 2

Navigation
 Startseite...
 Neuerdings beta neu
 Forum...
 vorwissen...
 vorkurse...
 Werkzeuge...
 Nachhilfevermittlung beta...
 Online-Spiele beta
 Suchen
 Verein...
 Impressum
Das Projekt
Server und Internetanbindung werden durch Spenden finanziert.
Organisiert wird das Projekt von unserem Koordinatorenteam.
Hunderte Mitglieder helfen ehrenamtlich in unseren moderierten Foren.
Anbieter der Seite ist der gemeinnützige Verein "Vorhilfe.de e.V.".
Partnerseiten
Weitere Fächer:

Open Source FunktionenplotterFunkyPlot: Kostenloser und quelloffener Funktionenplotter für Linux und andere Betriebssysteme
Forum "Softwaretechnik und Programmierung" - Geldbetrag Ausgabe in Eur/Cent
Geldbetrag Ausgabe in Eur/Cent < Softwaretechnik+Pro < Praktische Inform. < Hochschule < Informatik < Vorhilfe
Ansicht: [ geschachtelt ] | ^ Forum "Softwaretechnik und Programmierung"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien

Geldbetrag Ausgabe in Eur/Cent: Nachkommastellen in int
Status: (Frage) beantwortet Status 
Datum: 22:32 So 30.10.2011
Autor: steftn

Aufgabe
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    
    float Eingabe;
    int euro,cent;
    
    
    printf("Gib den Geldbetrag [mm] ein:\n"); [/mm]
  scanf("%f", &Eingabe);

  euro=(int)Eingabe;              
  Eingabe=Eingabe*100;
  cent=(Eingabe)-(euro*100);


  [mm] printf("\n\nDer [/mm] Betrag ist %d Euro und %d [mm] Cent\n\n", [/mm] euro, cent);
  system("PAUSE");
  return 0;
}


Hallo,

obiges Programm soll den Geldbetrag in Euro und Cent ausgeben.


Wenn man z.b. 568.98 Euro eingibt, kommt folgendes raus:

" Der Betrag ist 568 Euro und 98 Cent"

ok, das funktioniert soweit.

Als ich aber mehrere Beträge durchprobiert habe, klappte es bei diesen Betrag nicht:

147.15

Das Programm gibt dann " 147 Euro und 14 Cent" aus!!!!!!!!
Wiso stimmen die Cent nicht?????
Ich kann mir das nicht erklären, weiß das jemand wiso das nicht stimmt?

Ich wär für jeden Tipp dankbar :-)

        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Informationsverlust
Status: (Antwort) fertig Status 
Datum: 22:46 So 30.10.2011
Autor: Schadowmaster

moin steftn,

Beim Casten von Float zu Int gehen einige Infos verloren.
Es könnte sein, dass dies hier das Problem ist.
Versuche mal in der Berechnung des Centbetrags nicht euro selbst zu benutzen sondern die ursprüngliche Eingabe, also den Float und caste erst, nachdem berechnet wurde.
Vielleicht klappt es dann. ;)

lg

Schadow

Bezug
                
Bezug
Geldbetrag Ausgabe in Eur/Cent: Frage (beantwortet)
Status: (Frage) beantwortet Status 
Datum: 00:33 Mo 31.10.2011
Autor: steftn

Hallo,

danke für deine Antwort, aber leider komm ich nicht auf die Lösung.

Der "Cent-Wert", also quasi der Nachkommawert soll zu integer umgewandelt werden.

Folgendes hab ich gefunden:
http://msdn.microsoft.com/de-de/library/bb978923.aspx
"Rundungsfehler beim Umwandeln von Fließkommawerten in Ganzzahlwerte"

Anscheinend handelt es sich um ein größeres Problem.

mhm, hätt vielleicht jemand eine Lösung des Problems?


Bezug
                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Antwort
Status: (Antwort) fertig Status 
Datum: 01:53 Mo 31.10.2011
Autor: reverend

Hallo steftn,

> danke für deine Antwort, aber leider komm ich nicht auf
> die Lösung.
>  
> Der "Cent-Wert", also quasi der Nachkommawert soll zu
> integer umgewandelt werden.
>  
> Folgendes hab ich gefunden:
>  http://msdn.microsoft.com/de-de/library/bb978923.aspx
>  "Rundungsfehler beim Umwandeln von Fließkommawerten in
> Ganzzahlwerte"
>  
> Anscheinend handelt es sich um ein größeres Problem.
>  
> mhm, hätt vielleicht jemand eine Lösung des Problems?

Na, so tief in die Programmarchitektur willst Du doch bei so einer einfachen Fragestellung gar nicht einsteigen.

Um solche Fehler zu umgehen, ist es gut zu wissen, ob die Abweichung immer in der gleichen Richtung geschieht oder z.B. bei positiven und negativen Zahlen in jeweils entgegengesetzter Richtung auftritt.

Meist genügt es aber völlig, zur Vermeidung des Fehlers ein Korrekturglied einzufügen und durch Rundung (bzw. Abschneiden des Vor- oder Nachkommaanteils) wieder abzuschneiden.

Wenn f also die Fließkommazahl ist, e die Integerzahl "Euro" und c die Integerzahl "Cent" ist, kann wird das Korrekturglied k als Fließkommazahl so eingefügt:

e=int(f+k)
c=int(100*(f-e+k)) oder (je nach Fehlergröße) c=int(100*(f-e)+k)

Dabei sollte k wahrscheinlich in der Größenordnung [mm] 0.0025\le k\le{0.0075} [/mm] gewählt werden.
Beinhaltet der Befehl "int" (Ganzzahl) eine Rundungsroutine, dann sollte wahrscheinlich [mm]k<0.0025[/mm] gewählt werden.

Das ist die einfachste Lösung. Probiers mal aus.

Grüße
reverend


Bezug
                                
Bezug
Geldbetrag Ausgabe in Eur/Cent: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 02:52 Mo 31.10.2011
Autor: steftn

tadaaaaa, es funzt!!!! Super, vielen vielen dank :-)
Ich versteh zwar immer noch nicht ganz, wiso C da einen "Rundungsfehler?" macht, aber naja...


Hier mein neues funktionierendes Programm:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    
  float betrag,korr;
  int euro, cent;

  printf("Geben Sie einen Betrag ein: ");
  scanf("%f", &betrag);
  
  
  korr = 0.005;
  
   euro=(int)(betrag+korr);
   cent=(int)(100*(betrag-euro+korr));            


  [mm] printf("\n\nDer [/mm] Betrag [mm] von\n%d [/mm] Euro und %d [mm] Cent\nkann aus\n\n", [/mm] euro, cent);



  system("PAUSE");
  return 0;
}



....By the way: weiß jemand, wie man das ausschalten kann, dass hier dieses Forum nicht andauernd die C-Codes umwandelt??? Kann man den Mathematischen Textsatz hier irgendwie abstellen?
Kann man das abstellen: https://vorhilfe.de/mm

Bezug
                                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 03:51 Mo 31.10.2011
Autor: reverend

Hallo nochmal,

> tadaaaaa, es funzt!!!! Super, vielen vielen dank :-)

Schön, das ist erstmal die Hauptsache. Versuche, k so klein wie möglich und so groß wie nötig zu wählen. Probier dazu auch negative Betragseingaben.

>  Ich versteh zwar immer noch nicht ganz, wiso C da einen
> "Rundungsfehler?" macht, aber naja...

Die Erklärung, die Du selbst verlinkt hattest, ist dazu doch gar nicht schlecht.

> ....By the way: weiß jemand, wie man das ausschalten kann,
> dass hier dieses Forum nicht andauernd die C-Codes
> umwandelt??? Kann man den Mathematischen Textsatz hier
> irgendwie abstellen?

Man kann, aber es ist mühsam. Das Problem ist, dass man dazu wissen muss, was der Parser als LaTeX-interpretierbar erkennt. Diese Information ist aber nirgends dokumentiert, ich selbst weiß auch nur aufgrund einiger Eingabeerfahrung hier so ein paar Fallen.

Jedenfalls kannst Du die Formel-Interpretation vermeiden, indem Du die sonst automatisch interpretierten Stellen in eine Befehlsklammer einschließt (s.u.).

Die entsprechende Klammer für die LaTeX-Interpretation ist ja, wie dokumentiert, folgende: [mm]zu interpretierende Eingabe[/mm].

Der Parser erkennt nun automatisch (aber eben manchmal fehlerhaft), was im Formelsatz darzustellen ist, und fügt die Befehlsklammer ein.

Um das zu vermeiden, muss der Text, der automatisch erkannt wird, wie folgt geklammert werden: [ code ] Ausnahme [ /code ].

hmm. Schwer zu überlisten.
Natürlich gehören da keine Leerzeichen um die Anweisung code bzw. /code herum, sondern direkt die eckigen Klammern.

>  Kann man das abstellen: https://vorhilfe.de/mm

Tja, mal sehen, ob ich das hier überhaupt richtig eingegeben habe. Wenn nicht, wird es vielleicht noch ein paar Revisionen dauern...

So, soweit erst einmal die Textdarstellung.

Mit anderen Worten: häng lieber eine Text(-editor-)datei an, oder binde eine Grafik ein. In beiden Fällen fällt es ein bisschen schwer, direkt zu kommentieren oder korrigieren, aber wir kriegen das dann schon hin...

Grüße
reverend


Bezug
                                                
Bezug
Geldbetrag Ausgabe in Eur/Cent: Fehler bei großen Werten
Status: (Frage) beantwortet Status 
Datum: 04:26 Di 01.11.2011
Autor: steftn

Hallo,

nochmal bezüglich meines Programmes:

wenn ich als Korrekturfaktor 0.005 verwende, habe ich leider Probleme, wenn ich mit den Gelbeträgen in die 100.000-Marke komme... dann gibt es nämlich ab da wieder einen Rundungsfehler!

Dementsprechend muss ich dann den Korrekturwert anpassen, dann passt es wieder... das gleiche ist bei überschreitung der Million-Marke.

mhm, meine Lösung passt eigentlich schon, aber irgendwie bin ich selbst nicht damit zufrieden, dass ich ggf. den Korrekturwert anpassen muss.... mhm

Also eine 100%ige passende Lösung scheint es dann nicht zu geben? Vielleicht irgendein Befehl oder kleines Programm?

Bezug
                                                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Antwort
Status: (Antwort) fertig Status 
Datum: 06:51 Di 01.11.2011
Autor: Al-Chwarizmi


> Hallo,
>  
> nochmal bezüglich meines Programmes:
>  
> wenn ich als Korrekturfaktor 0.005 verwende, habe ich
> leider Probleme, wenn ich mit den Gelbeträgen in die
> 100.000-Marke komme... dann gibt es nämlich ab da wieder
> einen Rundungsfehler!
>  
> Dementsprechend muss ich dann den Korrekturwert anpassen,
> dann passt es wieder... das gleiche ist bei überschreitung
> der Million-Marke.
>  
> mhm, meine Lösung passt eigentlich schon, aber irgendwie
> bin ich selbst nicht damit zufrieden, dass ich ggf. den
> Korrekturwert anpassen muss.... mhm

... wirklich lästig
  

> Also eine 100%ige passende Lösung scheint es dann nicht zu
> geben? Vielleicht irgendein Befehl oder kleines Programm?


Hallo steftn,

über die z.T. etwas haarsträubenden Rundungsprobleme
in C++ habe ich mich schon auch gewundert. Im Netz
findet man dazu ganze Abhandlungen.

Für dein Problem sähe ich folgende Lösung:

x:     Betrag (float-Zahl)       (x>=0 vorausgesetzt)
e,c:   Euros, Cents (int-Zahlen)
cc:    Gesamtbetrag in Cents (int-Zahl)

1.) berechne  cc = floor(100*x+0.5)
2.) berechne  e  = floor(cc/100)
3.) berechne  c  = cc-100*e

Ich wäre erstaunt, wenn das auch noch zu Macken
führen würde ...

LG   Al-Chw.  


Bezug
                                                                
Bezug
Geldbetrag Ausgabe in Eur/Cent: Rundungsfehler immer noch da
Status: (Frage) beantwortet Status 
Datum: 14:01 Di 01.11.2011
Autor: steftn

Hallo,

@Al-Chwarizmi:

danke für deine Idee, aber leider funktioniert es bereits schon mit einigen 100.000-Werten nicht mehr richtig, da gibts wieder Rundungsfehler :-(

Hier das ausgetestete Programm nach deiner Idee:

[]Klick mich

Bezug
                                                                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Antwort
Status: (Antwort) fertig Status 
Datum: 15:04 Di 01.11.2011
Autor: reverend

Hallo steftn,

dann ändere mal noch zwei Zeilen:

e=floor(cc/100+0.5)
c=floor(cc-100*e+0.5)

Das ist jetzt echt brute force, aber wenn das nicht funktioniert, dann weiß ich schlicht nicht mehr weiter, ohne tatsächlich in die Variablenroutinen des Compilers einzutauchen. Falls ich die überhaupt verstehe, was eher unwahrscheinlich ist.

Grüße
reverend


Bezug
                                                                                
Bezug
Geldbetrag Ausgabe in Eur/Cent: Int-Umwandlung wieder falsch
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 18:12 Di 01.11.2011
Autor: steftn

Hallo,

@reverend:

danke für deine Idee. Hier das umgesetzte Programm:
[]Klick mich


Habs probiert. Manche 100.000-Werte gehen, manche nicht.
Der Wert hier geht z.b. nicht:

549786.14

Das Programm gibt dann folgendes aus:

Euro: 549786    Cent:13

Also gehts leider wieder nicht, schade :-(
gruß


Bezug
                                                                                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 22:24 Di 01.11.2011
Autor: Event_Horizon

Hallo!


Das Problem ist die Darstellung einer Fließkommazahl im Binärformat des Computers.

Ein INT beispielsweise kann aus 4 Byte bestehen, und kann damit jede ganze Zahl von -4'294'967'296 bis 4'294'967'295 darstellen. Man kann also sagen, daß das INT bis zu 10 Ziffern darstellen kann. ( wohl gemerkt, "bis zu". Die Zahl 8'000'000'000 geht NICHT)

Ein FLOAT besteht auch gerne aus 4 Byte, allerdings werden von diesen 32 Bit einige für den Exponenten benutzt, sodaß nicht mehr so viele für die eigentlichen Stellen übrig bleiben.

Die Präzision, d.h. die Anzahl der Stellen ist daher nicht sonderlich groß für ein FLOAT, dafür weiß es eben, ob es um "5 tausend", "5 Millonen", oder "5 hundert trillionen" geht.


Du kannst statt FLOAT ein DOUBLE benutzen, das hat meist 8 byte, und damit mehr Präzision. Allerdings auch nicht viel, die zusätzlichen Bits werden in erster Line dafür verwendet, noch größere Exponenten zu speichern. Das FLOAT kann maximal sowas wie [mm] 1^{38} [/mm] darstellen, das DOUBLE bis zu [mm] 10^{308} [/mm] . Aber ein paar mehr Bits gibt es schon für die Ziffern ansich.

Hier ein kleines Programm:

1:
2: #include <iostream>
3: #include <limits.h>
4: #include <iomanip>
5: using namespace std;
6:
7: int main() {
8:
9: float        f=549786.145678901234;
10: double       d=549786.145678901234;
11:
12: cout << "float:       "<< setprecision(20)<<  f <<endl;
13: cout << "double:      "<< setprecision(20)<<  d <<endl;
14:
15: return 0;
16: }


Das Programm definiert zwei Zahlen f und d als FLOAT und DOUBLE, und weist ihnen deine problematische Zahl zu. Ich habe noch ein paar Ziffern hinten dran gestellt, um das Problem zu verdeutlichen. Die Ausgabe des Programms sieht so aus:

float:       549786.125
double:      549786.14567890122999

Du siehst: Beim FLOAT stimmt schon die zweite Nachkommastelle nicht, das ergibt in deinem Programm sowas wie 12 oder 13Ct.

Das DOUBLE hält länger durch, hier stimmen noch 10 Nachkommastellen.


Warum genau das passiert, was hier passiert, ist etwas langatmig, aber du solltest wissen, daß die Anzahl an Stellen, die in einem float gespeichert werden können, nicht sonderlich groß ist.

Du solltest nun einfach ein DOUBLE verwenden, und dich damit abfinden, daß das Programm für die Staatsverschuldung so manchen Landes in nächter Zeit nicht richtig funktioniert. Aber auf die paar Ct. kommts dann auch nicht mehr an.





Bezug
                                                                                                
Bezug
Geldbetrag Ausgabe in Eur/Cent: Fehler bestehen weiterhin, OK
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 01:44 Mi 02.11.2011
Autor: steftn

@Event_Horizon:

vielen Dank für deine Ausführung, ich hab das Programm jetzt auf double umgebaut, siehe hier:

[]Klick mich

Bei einigen 100.000-Werten gibt es leider wieder Rundungsfehler, naja, zumindest hab ich jetzt gelernt, das man in C auf solche Sachen aufpassen muss.

Es kann also quasi keine 100%ige Lösung geben :-)

gruß

Bezug
                                                                                                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 01:48 Mi 02.11.2011
Autor: reverend

Hallo nochmal,

> @Event_Horizon:
>  
> vielen Dank für deine Ausführung, ich hab das Programm
> jetzt auf double umgebaut, siehe hier:
>  
> []Klick mich
>  
> Bei einigen 100.000-Werten gibt es leider wieder
> Rundungsfehler,

Das finde ich nach wie vor ziemlich unglaublich und nervig.

> naja, zumindest hab ich jetzt gelernt, das
> man in C auf solche Sachen aufpassen muss.
>  
> Es kann also quasi keine 100%ige Lösung geben :-)

Doch, es gibt immer einen Weg. Meist fragt man sich nur, warum bei einer so einfachen Aufgabe so kompliziert werden muss.

Du kannst die Eingabe natürlich auch als String lesen und Punkt oder Komma dann bei der Auswertung als Trenner erkennen. Erst nach der Zerlegung der Zeichenkette wandelst Du dann in ein Zahlenformat um.

Das kannst Du sogar notfalls schrittweise - also Stelle für Stelle - so tun, dass Du komplett mit Integer-Zahlen hinkommst.

Grüße
reverend


Bezug
                                                                                                                
Bezug
Geldbetrag Ausgabe in Eur/Cent: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 09:53 Mi 02.11.2011
Autor: Event_Horizon

Hallo!

Eine Sache seh ich noch:

Weil sich Kommazahlen schlecht von unserem Zehnersystem ins Binärsystem übertragen lassen, kommt es häufiger zu Rundungsfehlern.

Du gibst 1.15 als Zahl an, der Computer speichert das aber als 1,14999999999

Da du deine Cent als INT definiert hast, wird einfach die Nachkommastelle abgeschnitten, und dann bekommst du 14Ct raus.

Definier die cent auch mal als double, und formatier die im printf auch mit %lf. Dann solltest du diesen Effekt sehen können.


Bezug
                                                                                                                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 13:02 Mi 02.11.2011
Autor: chrisno

Da Du immer ganze ct haben wirst und haben willst, würde ich einen String einlesen. Dann kannst Du in Ruhe analysieren, ob überhaupt eine gültige Eingabe erfolgt ist: Ziffern evnetuell Komma danach bis zu zwei Ziffern. Den String zerlegst Du in zwei Integer und dann kann nichts böses mehr passieren.

Das habe ich mir für alle Eingaben angewöhnt, die von Anwendern kommen. Aber auch beim Einlesen aus Dateien ist das durchaus nützlich.

Bezug
                                                                                                        
Bezug
Geldbetrag Ausgabe in Eur/Cent: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 16:22 Mi 02.11.2011
Autor: Al-Chwarizmi


> zumindest hab ich jetzt gelernt, das
> man in C auf solche Sachen aufpassen muss.
>  
> Es kann also quasi keine 100%ige Lösung geben :-)


Es ist doch sehr beruhigend zu wissen, dass wegen
ähnlicher Softwareprobleme schon Raketen mit kostbarer
Nutzlast statt im All im Ozean angekommen sind.
Daneben wirken deine Probleme, bei denen es um plus
oder minus einen Cent geht, doch ziemlich bescheiden ...

(Vorsicht: das war absolut zynisch gemeint  ;-))

Al

Bezug
Ansicht: [ geschachtelt ] | ^ Forum "Softwaretechnik und Programmierung"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien


^ Seitenanfang ^
www.vorkurse.de
[ Startseite | Mitglieder | Teams | Forum | Wissen | Kurse | Impressum ]