ERLEDIGT
JA
JA
ANTWORTEN
10
10
ZUGRIFFE
343
343
EMPFEHLEN
-
Hallo allersetis,
ich muss folgendes Programmieren:
Ich soll beweisen das Gleitkommatypen mit den Operatoren + und * nicht assoziativ sind.
ich habe mir folgendes ausgedacht:
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
#include <iostream> #include <cstdlib> #include <cmath> #include <iomanip> using namespace std; void Assoziativ(){ // Allgemein gillt a+(b+c) = (a+b)+c // Allgemeint gillt (a*b)*c = a*(b*c) int a = 3; int b = 7; int c = 2; int result; result = a+(b+c); cout<<"3+(7+2) = "<<result<<endl; result = (a+b)+c; cout<<"(3+7)+2 = "<<result<<endl; } void BeweisFloat(){ float a = 0.05; float b = 0.70; float c =b-a; float result; //a+(b+c) result = a+(1+b); cout <<"res1 "<<result<<endl; result = (a+b)+1; cout <<"res2 "<<result<<endl; } void BeweisFloatv2(){ // Gleitkommatypen float, double und long double //double a = 10213.32452e10; double b=1; double c = 11.334; double res; //(a+b)+c double a = 6.*1024*1024*1024*1024*1024; double res; res= a; res=res+1; res=res+1; cout << setprecision(15) << setw(12) << res << endl; //cout<<res<<endl; //a+(b+c) res=a+2; cout << setprecision(15) << setw(12) << res << endl; //cout<<res<<endl; //result = a+result2; cout<<" "<<result<<" result 2 "<<result2<<endl; //cout<<endl; //result2 = (a+b); //result = result2+c; cout<<" "<<result<<" result 2 "<<result2<<endl; // } int main(){ Assoziativ(); cout<<endl; BeweisFloat(); system("pause"); return 0; }
ich habe eine Methode Beweis das zunächst zeigen soll was mit Assoziativ gemeint ist und mit den anderen Methoden habe ich versucht zu beweisen das mit dem Typ float das Assoziativgesetz nicht gilt. Ich habe aber das Problem das die beiden ergebnisse gleich sind statt unterschiedlich. Ich weiß nicht warum das so ist was mache ich falsch bzw. wie könnte ich es sonst beweisen ?Geändert von saeba (01.11.11 um 21:25 Uhr)
-
Hi und Willkommen bei tutorials.de

Zum Code: Bitte mach doch irgendeine Art von Zeileneinrückung und verwende cpp statt code.
So kann man das schwer lesen.
Zum Problem: Du sollst beweisen, dass das Assoziativg. für + und * nicht gilt!?
Das tut es aber.
Bei sämtlichen reellen Zahlen, egal ob ganz oder nicht,
sowie auch komplexen Zahlen und und...
Das ist völlig unabhängig von int/float, das ist einfach mathematischer Unsinn.
Oder meint dein Lehrer die computerbedingte Ungenauigkeit von Kommazahlen?Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Vielen Dank für die Antwort und für das Herzliche Willkommen
,
also der Prof meinte das es nicht Assoziativ ist da bei Gleitkommatypen die Reihenfolge der Verknüpfungen was ausmacht also das jeweil zwei unterschiedliche Ergebnisse rauskommen sollen. Allerdings habe so einiges probiert aber ich bekomme es irgendwie nicht hin oder geht das wirklich nicht ?
-
Hmm...ich nehm einfach mal an, dass die Ungenauigkeit/Begrenztheit
vom Computerspeicher gemeint ist.
zB. wenn man auf dem Papier mit 3/7 rechnet, kann man das ja als Bruch verwenden, ohne unendlich viel Kommastellen aufschreiben zu müssen.
Der Computer kanns aber nur so - und in den 32bit für ein float haben nur begrenzt viel Kommastellen Platz. Der Rest wird praktisch abgeschnitten. Das vorausgesetzt kann es bei anderer Rechenreihenfolge schon zu anderen Ergebnissen kommen.
3 Zahlen, die ich für * gefunden habe (rein zufällig):
1.8091
2.9038
3.8982
Für + schau ich noch...
edit: Für + gehen die drei genannten Zahlen auch.
Musst du auch erklären, warum es bei denen ungenau wird?Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
danke für deine schnelle Hilfe

also ich habe es gleich mal ausprobiert:
Code cpp:1 2 3 4 5 6
void BeweisFloat(){ float a = 1.8091; float b = 2.9038; float c =3.8982; float result; //a+(b+c) result = a+(c+b); cout <<"res1 "<<result<<endl; result = (a+b)+c; cout <<"res2 "<<result<<endl; }
ich erhalte folgende Ausgaben:
res1 8.6111
res2 8.6111
müssten eigentlich nicht jetzt unterschiedliche Ergebnisse rauskommen ? Kam bei dir unterschiedliche Ergebnisse raus ? Ja, also ich sollte das schon erklären können warum das ungenau wird aber ohne eien Beweis wird es schwierig
-
Ja, bei mir sinds unterschiedliche Ergebnisse.
Das Problem: Standardmäßig werden nicht alle möglichen Kommastellen ausgegeben, nur die ersten 4.
Wie man das bei cout umstellt müsste ich jetzt selbst nachschauen...aber bei printf gehts so:
Das statt den cout verwenden.Code cpp:1
printf("%.20f\n", result);
Zur theoretischen Erklärung: Hab jetzt leider nicht so viel Zeit, kommt aber in der Nacht noch.Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Hallo,
dein Prof hat in dem Sinne schon recht. Das Assoziativgesetz ist bei Gleitkomma-Darstellung nur eingeschränkt gültig. Vorallem bei Additionen und Multiplikationen von Zahlen aus anderen Größenordnungen kommt es zu diesen Abweichungen, die du finden sollst.
Dazu ein Beispiel:
Soll ein Computer zwei Zahlen addieren, muss der Computer die Exponenten der Zahlen angleichen, damit er sie addieren kann. Dadurch verschiebt sich ggf. auch die Mantisse der Zahlen, wodurch niederwertigere 1en verloren gehen könnten. So wird die Zahl in Extremsituationen sehr ungenau und demnach auch das Ergebnis.
Daher sollte man darauf achten in welcher Reihenfolge man Zahlen in seine Berechnung gibt, da sich sonst diese Ungenauigkeit verstärken oder abschwächen lässt.
Ich hoffe ich konnte dir helfen.
Grüße JennestaGeändert von Jennesta (02.11.11 um 00:58 Uhr) Grund: Rechtschreibfehler
Was soll daran kompliziert sein? Es muss doch nur ein Rad bewegt werden, man kann aufsteigen, es kommt die Matschhütte und durch den Regenbogen gelangst du zum hungrigen Affen, der Affenschwanz wird gezogen und bums kommst du zum Paradispark.
-
zunächst einmal was ich los werde muss ich finde es echt klasse das hier in diesem Forum ein geholfen wird
...
also ich habe das nun probiert:
Code cpp:1 2 3 4 5 6 7 8
void BeweisFloat(){ float a = 1.8091; float b = 2.9038; float c =3.8982; float result; //a+(b+c) result = a+(c+b); cout <<"res1 "<<result<<endl; printf("%.20f\n", result); result = (a+b)+c; cout <<"res2 "<<result<<endl; printf("%.20f\n", result); }
und ich erhalte folgende Ausgabe http://imgup.com/share-6A34_4EB095D7.html
ich habe trotzdem zwei mal das selbe Ergebnis
@Jennesta
also im Prinzip verstehe ich was du meinst, ich hatte sowas schon mal gelesen gehabt allerdings ist es gar nicht so einfach die Zahlen und die Reihenfolge so zu wählen oder ich mach was falsch oder rundet mein Compiler auf ****?
-
Hi
sorry, dass doch noch nichts mehr gekommen ist...verschlafen
Zuerst mal zum Code:
Es kann sein, dass dein Compiler die Berechnung wegoptimiert.
Es sind ja in jedem Fall die gleichen Zahlen mit dem (eigentlich) gleichen Ergebnis...
nicht von Benutzereingaben etc. abhängig.
Mach
a) cin-Eingaben für die 3 floats, und die passenden Werte eben eintippen.
b) die Berechnung nicht in eine Zeile.
Also sowas:
Code cpp:1 2 3 4 5
cin >> a; cin >> b; result = a + b; cin >> c; result = c;
Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
02.11.11 13:04 #10
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
Hi.
Folgendes funktioniert bei mir:
Mit float könnte es etwas schwieriger werden, da Prozessoren (abhängig des vom Compiler erzeugten Maschinencodes) die Operation evtl. mit höherer Genauigkeit ausführen und dann einfach zum Schluß abschneiden. Welchen Compiler verwendest du denn?Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#include <iostream> #include <cstdio> #include <iomanip> using namespace std; int main(int argc, char *argv[]) { double a = 1234.567, b = 45.67834, c = 0.0004; double result1, result2; result1 = c + b; result1 += a; result2 = (a+b); result2 += c; cout << "ungleich? " << boolalpha << (result1 != result2) << endl; cout << setprecision(20) << result1 << endl << result2 << endl; }
GrußIf at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
Ok ich habe das Problem für die Addition gelöst
Code cpp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
void BeweisFloat(){ double a = 1E-100; double b = 1E+100; double c = 1E+10; double res; printf("%.20f\n", a); printf("%.20f\n", b); printf("%.20f\n", c); cout<<"a "<<a<<endl; cout<<"b "<<b<<endl; cout<<"c "<<c<<endl; //a+(b+c) res = a*(b*b); cout <<"res1 "<<res<<endl; printf("%.20f\n", res); res = (a*b)*b; cout <<"res2 "<<res<<endl; printf("%.20f\n", res); }
damit bekomme ich unterschiedliche Ergebnisse...
@deepthroat danke für deine Hilfe, also ich benutze den MingCompiler, werde deins mal testen...für die Multiplikation habe ich noch keine passenden zahlen gefunden, naja...
Ähnliche Themen
-
Problem beim Login in den SQL Server, bzw. generelles Problem auf Datenbankzugriff
Von Trigoor2 im Forum .NET DatenverwaltungAntworten: 7Letzter Beitrag: 25.10.11, 08:29 -
[IE7 Problem] Problem mit ul/li Höhen im IE7 bei Verwendung eines vertikalen Menüs
Von josDesign im Forum CSSAntworten: 0Letzter Beitrag: 11.01.11, 21:40 -
Gleitkommatypen
Von chillermiller im Forum C/C++Antworten: 1Letzter Beitrag: 05.12.08, 15:53 -
Problem: Flash MX (7.1) exportiert meine Fla nicht mehr - dringendes Problem
Von Lukasz im Forum Flash PlattformAntworten: 4Letzter Beitrag: 22.03.06, 20:50 -
Problem mit PopUp (Ja ich weiss Suche benutzten, hab ein ganz anderes Problem)
Von killkrog im Forum Javascript & AjaxAntworten: 6Letzter Beitrag: 13.06.02, 12:29





Zitieren

Login






