Rundungsfehler ?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
indianer-frank
Beiträge: 134
Registriert: So 30. Nov 2008, 21:53

Re: Rundungsfehler ?

Beitrag von indianer-frank »

siro hat geschrieben:Eigentlich feht dann im SetRoundMode rmNormal oder rmSchool rmMiddle rmDrawing oder wie man das auch nennen mag.

Meinst Du wirklich, daß eine FPU sich dadurch ändern läßt? Diese Modi sind i.a. in Hardware/Firmware implementiert!

Der IEEE-Standard definiert Euren gewünschten Modus als (hier zunächst der englische Wiki-Eintrag https://en.wikipedia.org/wiki/IEEE_floa ... to_nearest):
Round to nearest, ties away from zero – rounds to the nearest value; if the number falls midway it is rounded to the nearest value above (for positive numbers) or below (for negative numbers); this is intended as an option for decimal floating point.

und in Deutsch https://de.wikipedia.org/wiki/IEEE_754#Rundungen

IEEE 754 unterscheidet zunächst zwischen binären Rundungen und binär-dezimalen Rundungen, bei denen geringere Qualitätsforderungen gelten.

Bei binären Rundungen muss zur nächstgelegenen darstellbaren Zahl gerundet werden. Wenn diese nicht eindeutig definiert ist (genau in der Mitte zwischen zwei darstellbaren Zahlen), wird so gerundet, dass das niederwertigste Bit der Mantisse 0 wird. Statistisch wird dabei in 50 % der Fälle auf-, in den anderen 50 % der Fälle abgerundet, so dass die von Knuth beschriebene statistische Drift in längeren Rechnungen vermieden wird.

Eine zu IEEE 754 konforme Implementierung muss drei weitere vom Programmierer einstellbare Rundungen bereitstellen: Rundung gegen +Unendlich (immer aufrunden), Rundung gegen −Unendlich (immer abrunden) und Rundung gegen 0 (Ergebnis immer betragsmäßig verkleinern).


Und hier noch die relevanten Abschnitte aus dem IEEE-754/2008-Standard (4.3.1 und 4.3.3)

Code: Alles auswählen

 
― roundTiesToEven, the floating-point number nearest to the infinitely precise result shall be
delivered; if the two nearest floating-point numbers bracketing an unrepresentable infinitely
precise result are equally near, the one with an even least significant digit shall be delivered
 
― roundTiesToAway, the floating-point number nearest to the infinitely precise result shall be
delivered; if the two nearest floating-point numbers bracketing an unrepresentable infinitely
precise result are equally near, the one with larger magnitude shall be delivered.
 
...
 
An implementation of this standard shall provide roundTiesToEven and the three directed rounding
attributes. A decimal format implementation of this standard shall provide roundTiesToAway as a user-
selectable rounding-direction attribute. The rounding attribute roundTiesToAway is not required for a
binary format implementation.
 

Wie man sieht, ist der Schulbuch-Modus bei konformer dezimaler Implementation auswählbar (BCD?)

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Rundungsfehler ?

Beitrag von Mathias »

Ich habe es mit LibreOffice und in der Firma mit Excel probiert. Dort wird alles .5 aufgerundet. Schon interessant, das ausgerechnet Tabellenkalkulationen kein Bankenrunden verendet.

Als Formel habe ich folgendes verwendet:

Code: Alles auswählen

=RUNDEN(A1) 
=RUNDEN(A2)
=RUNDEN(A3)
usw.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Rundungsfehler ?

Beitrag von Socke »

Mathias hat geschrieben:Ich habe es mit LibreOffice und in der Firma mit Excel probiert. Dort wird alles .5 aufgerundet. Schon interessant, das ausgerechnet Tabellenkalkulationen kein Bankenrunden verendet.

Ein Office-Programm würde ich nicht unbedingt als Referenz für mathematische Standardverfahren verwenden (https://futurezone.at/science/excel-feh ... 17.612.031). Als Referenz für Office-Programme hingegen finde ich deren Einsatz einwandfrei nutzbar. :P
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Rundungsfehler ?

Beitrag von wp_xyz »

Wolfram Alpha (https://www.wolframalpha.com/), was ich eher als Referenz für ein Mathematik-Programm ansehe, verwendet übrigens auch Banker's Rounding:

Code: Alles auswählen

  round(0.5) = 0
  round(1.5) = 2
  round(2.5) = 2

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Rundungsfehler ?

Beitrag von wp_xyz »

Socke hat geschrieben:
Mathias hat geschrieben:Ich habe es mit LibreOffice und in der Firma mit Excel probiert. Dort wird alles .5 aufgerundet. Schon interessant, das ausgerechnet Tabellenkalkulationen kein Bankenrunden verendet.

Ein Office-Programm würde ich nicht unbedingt als Referenz für mathematische Standardverfahren verwenden (https://futurezone.at/science/excel-feh ... 17.612.031).

Ich sehe das im Prinzip genauso, allerdings wundere ich mich, dass die super ausgestatteten GenTechnik-Labore keine andere Software haben. Und wenn einem Autor in einer wissenschaftlichen Publikation nicht auffällt, dass Excel einen Namen in ein Datum umgewandelt hat, dann frage ich mich, wie genau er sich überhaupt seine Daten angesehen hat. Die Schlagzeile des zitierten Artikels "Microsofts Excel konvertiert viele Namen von Genen in Tabellen standardmäßig zu Datumsangaben. Ein Fünftel der Fachveröffentlichungen enthalten solche Fehler." würde ich positiv formulieren: "Microsofts Excel deckt auf, dass bei einem Fünftel de Genetik-Veröffentlichungen keine kritische Datenanalyse durchgeführt wurde."

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Rundungsfehler ?

Beitrag von mschnell »

Mathias hat geschrieben:Ich habe für SetRoundMode noch ein kleine Wiki geschrieben: http://wiki.freepascal.org/SetRoundMode/de

Was ist denn der Unterschied zwischen "Dezimalstellen abschneiden" und "zum nächst kleineren integer abrunden" ?
Edit:
Ah, verstehe, Runden "Gegen 0", und "Runden gegen -Unendlich".
Die Deutsche Beschreibung finde ich ziemlich missverständlich.

Eine Möglichkeit 0.5 -> 1 und 0.3 -> 0 rundet ist da aber nicht beschrieben.

-Michael
Zuletzt geändert von mschnell am Mo 4. Jun 2018, 11:51, insgesamt 3-mal geändert.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Rundungsfehler ?

Beitrag von mschnell »

siro hat geschrieben:Fragt mal eure Eltern wie sie 3,5 runden würden. Die meistens sagen ab 0,5 nach oben.
Dann programmiert man in Pascal und es geht garnicht, man kann das nichtmal einstellen, das ist schon traurig....l

Fragt mal eure Ur-Ur-... Großeltern ob sich die Sonne um die Erde dreht dreht ....

-Michael

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rundungsfehler ?

Beitrag von siro »

Ich komme ja noch aus den alten Turbo Pascal Zeiten und da wurde tatsächlich noch anders gerundet,
nämlich so:

Turbo Pascal Version 3
ROUND
Syntax: Round(Num);
Returns the value of Num rounded to the nearest integer as follows: if
Num >- 0, then Round(Num) = Trunc(Num + 0.5). If Num < 0, then
Round(Num) = Trunc(Num - 0.5). Num must be of type Real, and the
result is of type Integer.

0.5 ==> 1
1.5 ==> 2
2.5 ==> 3

warum muste man das ändern ? Daher wäre mein "rmDefault" eigentlich rmTurboPascalRound
aber das wurde ja gänzlich entsorgt, das kann man nichtmal einstellen.

Wenn man es weis ist das ja alles okay, wenn man es aber anders gelernt hat wundert man sich schon. "Früher war alles besser"
Für mich war Turbo Pascal das "A" und "O" überhaupt, war ja schon fast süchtig danach... :mrgreen:
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Rundungsfehler ?

Beitrag von af0815 »

Ich glaube mit Turbo Pascal fällt man schon in die Ur-, Ur-, ... Großeltern Kategorie :-) SCNR.

Ich habe das mit den Bankersrounding auch nicht dem 'normalen' rounding zugeordnet.

Andreas

BTW. Mit TP 3.0 CP/M (+MSX-DOS) auf einer Z80 habe ich begonnen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rundungsfehler ?

Beitrag von siro »

Turbo Pascal 3 war doch erst 1986, also grade mal 32 Jahre
Willkommen im Club der 55 Jährigen Andreas,
Auch wenns nicht mehr ganz so "round" läuft, ist der Bauch zuminndest "round"... :lol:
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Rundungsfehler ?

Beitrag von mschnell »

siro hat geschrieben:Ich komme ja noch aus den alten Turbo Pascal Zeiten und da wurde tatsächlich noch anders gerundet,

Wie bereits mehrfach erwähnt, liegt das nicht am Compiler, sondern an der Hardware.

Wenn Turbo Pascal nicht explizit den MyRound "Trick" anwendet, die Floatingpoint-Hardware verwendet und falls das Programm auf einem aktueller Chip läuft kommt vermutlich dasselbe heraus wie bei einem mit neustem fpc übersetzten Executable.

-Michael
Zuletzt geändert von mschnell am Di 5. Jun 2018, 10:06, insgesamt 1-mal geändert.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Rundungsfehler ?

Beitrag von Mathias »

Wenn FPC nicht explizit den MyRound "Trick" anwendet, die Floatingpoint-Hardware verwendet und falls das Programm auf einem aktueller Chip läuft kommt vermutlich dasselbe heraus wie bei einem mit neustem fpc übersetzten Executable.

Man müsste mal folgendes mit Turbo-Pascal übersetzen und dies nativ auf einem modernen Rechner laufen lassen.
Hat hier zufällig noch jemand ein 32Bit Windows nativ am laufen ?
Die DOSBox will ich nicht nehmen, da diese sowieso ein Emulator ist.

Code: Alles auswählen

{$N+}
begin
  WriteLn(round(0.5));
  WriteLn(round(1.5));
  WriteLn(round(2.5));
  WriteLn(round(3.5));
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

indianer-frank
Beiträge: 134
Registriert: So 30. Nov 2008, 21:53

Re: Rundungsfehler ?

Beitrag von indianer-frank »

Mathias hat geschrieben:Man müsste mal folgendes mit Turbo-Pascal übersetzen und dies nativ auf einem modernen Rechner laufen lassen.
Hat hier zufällig noch jemand ein 32Bit Windows nativ am laufen ?
Die DOSBox will ich nicht nehmen, da diese sowieso ein Emulator ist.

Code: Alles auswählen

{$N+}
begin
  WriteLn(round(0.5));
  WriteLn(round(1.5));
  WriteLn(round(2.5));
  WriteLn(round(3.5));
end.

Das Ergebnis wird Dich hoffentlich überraschen. Der Ur-Alt-Compiler 4.0 von 1987 benutzt Round-to-Even, ebenso TP5, BP7! Die neueren
haben allerdings noch eine weitere Überraschung: Literale werden anders als Variable behandelt: Hier das Testprogram

Code: Alles auswählen

{$F-,I+,L+,N+,R-,S-,V+}
{$M 32000,0,655360}
 
procedure test1;
begin
  writeln('Via Literal');
  writeln(round(0.5));
  writeln(round(1.5));
  writeln(round(2.5));
  writeln(round(3.5));
end;
 
procedure test2;
var
  l: longint;
  x: extended;
begin
  writeln('Via Variable');
  x := 0.5;  l:= round(x); writeln(l);
  x := 1.5;  l:= round(x); writeln(l);
  x := 2.5;  l:= round(x); writeln(l);
  x := 3.5;  l:= round(x); writeln(l);
end;
begin
  test1;
  test2;
end.
 

und das Protokoll:

Code: Alles auswählen

 
D:\BP_WE\WORK\AMath>ver
Windows 98 [Version 4.10.1998]
 
D:\DMX\TP4>TPC.EXE T_RND.PAS
Turbo Pascal  Version 4.0  Copyright (c) 1987 Borland International
T_RND.PAS(29)
29 lines, 3904 bytes code, 585 bytes data.
D:\DMX\TP4>T_RND.EXE
Via Literal
0
2
2
4
Via Variable
0
2
2
4
 
D:\BP_WE\WORK\AMath>p5 T_RND.PAS
Turbo Pascal  Version 5.0  Copyright (c) 1983,88 Borland International
T_RND.PAS(29)
29 lines, 4432 bytes code, 664 bytes data.
D:\BP_WE\WORK\AMath>T_RND.EXE
Via Literal
1
2
3
4
Via Variable
0
2
2
4
 
D:\BP_WE\WORK\AMath>bpc -b T_RND.PAS
Borland Pascal  Version 7.0  Copyright (c) 1983,92 Borland International
T_RND.PAS(29)
29 lines, 4720 bytes code, 690 bytes data.
D:\BP_WE\WORK\AMath>T_RND.EXE
Via Literal
1
2
3
4
Via Variable
0
2
2
4
 

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Rundungsfehler ?

Beitrag von af0815 »

GEIL :shock: :oops:
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rundungsfehler ?

Beitrag von siro »

Man konnte früher sogar in den Optionen einstellen ob der Coprozessor benutzt werden soll oder die Emulation,
ich weis garnicht ob die Rundungsergebnisse dann unterschiedlich waren. Habe leider kein Turbo Pascal mehr.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten