Mathematik für Computerbegeisterte

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Mathematik für Computerbegeisterte

Beitrag von Xin » Do Mär 08, 2012 3:59 pm

oenone hat geschrieben:Mit Fixkommazahlen mit mind. einer Nachkommastelle ist 0.1 perfekt binär darstellbar. Dadurch ist das Problem gelöst, oder nicht? Habe ich vielleicht das falsche Problem versucht zu lösen? bin ein wenig verwirrt :?
0.1 ist dezimal. Computer rechnen binär.
0.1 binär ist 0.5 dezimal.
0.1 dezimal ist binär nicht in endlicher Form formulierbar. Also muss man irgendwann mit der Beschreibung aufhören. Damit ist die binäre Zahl aber eben nicht genau 0.1 dezimal.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Mathematik für Computerbegeisterte

Beitrag von cloidnerux » Do Mär 08, 2012 4:19 pm

Mit Fixkommazahlen mit mind. einer Nachkommastelle ist 0.1 perfekt binär darstellbar. Dadurch ist das Problem gelöst, oder nicht? Habe ich vielleicht das falsche Problem versucht zu lösen? bin ein wenig verwirrt
Das Problem ist Folgendes:
Dezimal:

Code: Alles auswählen

10^2 10^1 10^0 10^-1 10^-2
  0    1    1    1    1    = 11,11
Binär:

Code: Alles auswählen

2^2 2^1 2^0 2^-1 2^-2
 1    1   1   1    1 = 7,75 Dezimal
Damit ergibt sich für den Nachkommateil eine Summe aus 1/2^n und diese verhält sich nicht genauso wie eine Summe von x_n*1/10^n wie bei Dezimalzahlen.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
oenone
Beiträge: 223
Registriert: Do Sep 01, 2011 2:42 pm
Wohnort: Bremen
Kontaktdaten:

Re: Mathematik für Computerbegeisterte

Beitrag von oenone » Do Mär 08, 2012 5:00 pm

Xin hat geschrieben:0.1 ist dezimal. Computer rechnen binär.
Das ist mir klar. Allerdings kann ich eine Datenstruktur definieren, die eine fixe Anzahl an dezimalen Nachkommastellen darstellt.

Eine einfache Implementierung wäre z.B. die Zahl einfach ohne das Komma ins Binäre zu übersetzen. Da die Anzahl an Nachkommastellen bekannt ist, wird bei Konvertierungen (z.B. für Ausgabe) das Komma wieder eingefügt. Damit wäre 0.1 intern wie eine 1 dargestellt.

Genau sowas gibt es bei Ada von Haus aus mit. Ich kann durch "type Fixed is digits 1;" festlegen, dass der Typ "Fixed" eine dezimale Nachkommastelle enthält. Intern werden zwar weiterhin IEEE-Floats benutzt, aber bei den Berechnungen werden die zusätzlichen Einschränkungen berücksichtigt, wodurch aus (666.6-666.5)*10000 auch wirklich 1000.0 raus kommt.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Mathematik für Computerbegeisterte

Beitrag von Xin » Do Mär 08, 2012 5:26 pm

oenone hat geschrieben:
Xin hat geschrieben:0.1 ist dezimal. Computer rechnen binär.
Das ist mir klar. Allerdings kann ich eine Datenstruktur definieren, die eine fixe Anzahl an dezimalen Nachkommastellen darstellt.
Ja, das geht.
Das wäre a) kein Primitiv, daher b) langsam beim rechnen und c) löst es das grundsätzliche Problem nicht, dass mit begrenzten Speicher Rundungsfehler entstehen, denn...
oenone hat geschrieben:Eine einfache Implementierung wäre z.B. die Zahl einfach ohne das Komma ins Binäre zu übersetzen. Da die Anzahl an Nachkommastellen bekannt ist, wird bei Konvertierungen (z.B. für Ausgabe) das Komma wieder eingefügt. Damit wäre 0.1 intern wie eine 1 dargestellt.
...dann speichere mal 0.01. :-D
oenone hat geschrieben:Genau sowas gibt es bei Ada von Haus aus mit. Ich kann durch "type Fixed is digits 1;" festlegen, dass der Typ "Fixed" eine dezimale Nachkommastelle enthält. Intern werden zwar weiterhin IEEE-Floats benutzt, aber bei den Berechnungen werden die zusätzlichen Einschränkungen berücksichtigt, wodurch aus (666.6-666.5)*10000 auch wirklich 1000.0 raus kommt.
Das hätte ich dann gerne erstmal bewiesen. ^^
Könntest Du das Ergebnis mal auf 25 Nachkomma-Stellen ausgeben?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
oenone
Beiträge: 223
Registriert: Do Sep 01, 2011 2:42 pm
Wohnort: Bremen
Kontaktdaten:

Re: Mathematik für Computerbegeisterte

Beitrag von oenone » Do Mär 08, 2012 7:17 pm

Dafür müsste ich "digits 25" benutzen, allerdings unterstützt die GNAT-Implementierung nur 18 Nachkommastellen. Im Übrigen habe ich mich ein wenig geirrt, wenn ich nur "digits x" angebe, ist es weiterhin ein Floating Point typ, allerdings mit x dezimalen Nachkommastellen.

Für Fixed Point muss ich noch ein delta angeben.

Beispiel:

Code: Alles auswählen

with Ada.Text_IO;
procedure Fixed is
   type Fixed_Point is delta 0.000000001 range 0.0 .. 1.0;
   package Fixed_IO is new Ada.Text_IO.Fixed_IO (Fixed_Point);
begin
   Ada.Text_IO.Put ("0.1 = ");
   Fixed_IO.Put (0.1);
   Ada.Text_IO.New_Line;
end Fixed;
Ausgabe:

Code: Alles auswählen

0.1 =  0.100000000
Aber ich stimme dir zu, nummerische Berechnungen sind meistens Fehlerbehaftet und man sollte das berücksichtigen.

Antworten