PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C: Falsche Berechnung?



itsme
19-01-2004, 21:34
Wenn ich das folgende simple Programm mit GCC kompiliere und ausführe bekomme ich als Ergebnis 50'000'004.



void main()
{
float test = 50000000;
float test2 = 5;

float result = test + test2;

printf("%f", result);
}


Wenn ich es mit VC++ kompiliere erhalte ich, wie ich eigentlich erwartet habe 50'000'005. Weiss jemand wieso ich mit dem GCC das falsche Ergebnis erhalte?

peschmae
19-01-2004, 21:59
Bei mir auch :eek:

Aber float sollte doch normalerweise sogar noch eine Stelle mehr vertragen :confused:

MfG Peschmä

wraith
19-01-2004, 22:04
Das liegt an der Ungenauigkeit der Fließkommazahlen,in diesem Fall ist der Grund aber nicht in der Rechnung (wenn du 50000005 hardcodest und ausgibst,dann wird auch 50000004 angezeigt).

Um den Nullpunkt herum gibt es sehr viele FP Zahlen,aber mit zunehmender Entfernung wird der Zahlenstrahl 'löchriger' (klar 32 Bit sind ja auch nicht so viel).Was dazu führt,das nicht mal mehr jede Ganzzahl dargestellt werden kann,und dann muß ebend zur nächsten gerundet werden.

Btw, bei mir unterscheidet sich das Ergebnis von gcc 3.3 und VC 7.1 nicht (beide können 50000005 nicht exakt darstellen)

itsme
19-01-2004, 22:14
Hmm, weiss jemand wie ich das umgehen kann? Bei gewissen Applikationen ist man ja durchaus auf genaue Werte angewiesen.

Alex_K
19-01-2004, 22:27
indem du double statt float nimmst.

anda_skoa
19-01-2004, 23:31
Für sehr hohe Stellenanzahl bei gleicher Genaugigkeit musst du eine eine Lib wie zB GNU MP zurückgreifen
http://www.swox.com/gmp/

Ciao,
_

peschmae
20-01-2004, 14:37
Hmm, ich hab immer gedacht, bei float seien es jeweils 16bit basis und 16bit Exponent. Offenbar nicht :confused:

Was denn?

MfG Peschmä

lacsap
20-01-2004, 16:13
Original geschrieben von peschmae
Hmm, ich hab immer gedacht, bei float seien es jeweils 16bit basis und 16bit Exponent. Offenbar nicht :confused:

Was denn?

MfG Peschmä

Nach meinen unterlagen nach IEEE 754

vorzeichen: 1 Bit
exponent: 8 Bit
mantisse: 23 Bit

peschmae
20-01-2004, 17:07
ok, jetzt isses klar.

MfG Peschmä

Shack
20-01-2004, 18:44
na jetzt habt ihr bei mir ja ne Frage generiert.

In einem Interger (2Byte), kann man wenn er unsigned ist, eine Zahl von maximal 65535 speichern, richtig ? Und das wei 2 hoch 16 gleich diese Zahl ist.

dem entsprechent ist es bei einem Long 2 hoch 32 = 4 Mrd + irgendetwas.

Und wie ist das jetz bei nem Float, der ist 32 Bit groß, also eigentlich wie ein Long.
Aber in welchem Zusammenhang stehen die Zahlen vor dem Komma mit Zahlen nach dem Komma? Und was meint ihr mit Mantisse bzw. Exponent?

peschmae
20-01-2004, 19:33
ein "normaler" int ist 4 Byte - zumindest bei mir

In was für ner Klasse bist? Float-Zahlen werden in der Scifi-Notation gespeichert - z.B.
3.94124798124*10^3 ist dann 394.1248...

Matisse (bei uns wird das als Basis bezeichnet) ist hier 394124798124 und Exponent ist 3

In einer Float-Zahl werden also quasi die ersten ~7 signifikanten Ziffern plus wo das Komma dann hinkommt gespeichert.

Es ist keinesfalls so, dass so eine float-Zahl aus einem Int für alles vor und einem Int für alles nach dem Komma bestehen würde...

Alles unklar?

MfG Peschmä

Shack
20-01-2004, 20:05
In was für ner Klasse bist?

?????????????????????



ein "normaler" int ist 4 Byte - zumindest bei mir

so ist das nicht schon immer ! Und sollte nur ein Rechenbeispiel sein.



In einer Float-Zahl werden also quasi die ersten ~7 signifikanten Ziffern plus wo das Komma dann hinkommt gespeichert.

wo werden denn nun die Zahlen nach dem komma gespeichert und wie lang kann denn nun der Rattenschwanz sein ?

anda_skoa
20-01-2004, 21:17
Original geschrieben von Shack
so ist das nicht schon immer ! Und sollte nur ein Rechenbeispiel sein.

Auf 16Bit Systemen wie dem 286 war das noch 2 Byte, auf 32Bit oder höher ist es praktisch immer 4 Byte (32Bit), also die normale Datenbusbreite.
Ist aber theoretisch dem Compiler überlassen, er darf einen int auch 1 Byte lang machen, solange char nicht größer ist.



wo werden denn nun die Zahlen nach dem komma gespeichert und wie lang kann denn nun der Rattenschwanz sein ?

Das wird alles in den selben 32bit gespeichert.
Wenn ich mich recht erinnere zuerst das Vorzeichenbit (1 -> negativ), dann die Mantisse, dann der Exponent.
Wobei der Exponent mit einem Offset versehen ist, Exponent 0 ist dann ^-128
Hmm, weiß gerade nicht, ob der Expontent zu Basis 2 oder 10 ist :(

Bei der Mantisse gibts auch einen Trick, da wird glaub ich die Stelle vor dem Komma immer mit einem festern Wert angenommen, IIRC 0.

Ciao,
_

peschmae
20-01-2004, 22:04
@anda_skoa: autsch, schöner Patzer :D - stimmt ist basis 2. Sonst gehts nicht auf.


std::cout << std::numeric_limits<float>::max() << '\n';

liefert nämlich 3.40282e+38

Mit Basis 10 sollte da statt 38 eher 128 stehen

@Shack: War nicht so nett - sorry :(
Imo sollte nämlich jeder ab 7. Klasse mit den Begriffen Matisse und Exponent bzw. Basis und Exponent was anfangen können.


von weiter oben
Nach meinen unterlagen nach IEEE 754

vorzeichen: 1 Bit
exponent: 8 Bit
mantisse: 23 Bit


Reihenfolge dürfte ja egal sein. Für die meisten.

MfG Peschmä

Shack
20-01-2004, 22:44
schon o.k.

was basis und exponent ist , ist schon klar. in dem zusammenhang war es erstmal für mich zu hinterfragen. wußte nicht das die exponenten mitgespeichert werden.

Bin davon ausgegangen , das der Speicherbereich komplett mit 1-en oder 0-en
voll geschrieben wird.

Aber habt vielen Dank , das auch diese Lücke geschlossen wurde.

peschmae
21-01-2004, 09:28
aber der Speicherbereich wird doch komplett mit 0en und 1en vollgeschrieben :confused:

Das versteh ich jetzt nicht ganz.

MfG Peschmä