Rundungsfehler ?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

Re: Rundungsfehler ?

Beitragvon indianer-frank » 1. Jun 2018, 09:04 Re: Rundungsfehler ?

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?)
indianer-frank
 
Beiträge: 133
Registriert: 30. Nov 2008, 21:53

Beitragvon Mathias » 1. Jun 2018, 17:44 Re: Rundungsfehler ?

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 gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Socke » 1. Jun 2018, 22:30 Re: Rundungsfehler ?

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
Socke
 
Beiträge: 2546
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon wp_xyz » 1. Jun 2018, 23:06 Re: Rundungsfehler ?

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: 2644
Registriert: 8. Apr 2011, 08:01

Beitragvon wp_xyz » 1. Jun 2018, 23:15 Re: Rundungsfehler ?

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."
wp_xyz
 
Beiträge: 2644
Registriert: 8. Apr 2011, 08:01

Beitragvon mschnell » 4. Jun 2018, 10:39 Re: Rundungsfehler ?

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 4. Jun 2018, 10:51, insgesamt 3-mal geändert.
mschnell
 
Beiträge: 3226
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon mschnell » 4. Jun 2018, 10:43 Re: Rundungsfehler ?

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
mschnell
 
Beiträge: 3226
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon siro » 4. Jun 2018, 12:16 Re: Rundungsfehler ?

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...
siro
 
Beiträge: 305
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

Beitragvon af0815 » 4. Jun 2018, 14:15 Re: Rundungsfehler ?

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).
af0815
 
Beiträge: 3479
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon siro » 4. Jun 2018, 14:51 Re: Rundungsfehler ?

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...
siro
 
Beiträge: 305
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

Beitragvon mschnell » 4. Jun 2018, 15:09 Re: Rundungsfehler ?

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 5. Jun 2018, 09:06, insgesamt 1-mal geändert.
mschnell
 
Beiträge: 3226
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon Mathias » 4. Jun 2018, 17:35 Re: Rundungsfehler ?

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 gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon indianer-frank » 4. Jun 2018, 18:58 Re: Rundungsfehler ?

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
 
indianer-frank
 
Beiträge: 133
Registriert: 30. Nov 2008, 21:53

Beitragvon af0815 » 4. Jun 2018, 20:44 Re: Rundungsfehler ?

GEIL :shock: :oops:
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3479
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon siro » 4. Jun 2018, 21:47 Re: Rundungsfehler ?

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...
siro
 
Beiträge: 305
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

» Weitere Beiträge siehe nächste Seite »
VorherigeNächste

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: braunbär und 7 Gäste

porpoises-institution
accuracy-worried