Hallo zusammen, ich bin neulich über ein Codeschnipsel in einem großen Programm gestolpert. Dort wird die Kreiszahl Pi in einer etwa 15 Zeilen langen Funktion berechnet, obwohl in der selben Datei die <math.h> eingebunden ist, und somit der Zugriff auf "M_PI" möglich wäre. Die Funktion liefert als Rückgabetyp einen "long double". Genauer als 20 Stellen wird's ja deswegen auch nicht, oder? Was ist der Sinn der Sache, dass der Programmierer Pi in einer Funktion berechnet, anstatt auf die definierte Konstante mit 20 Nachkommastellen zuzugreifen? Ich bin nicht dahintergekommen. Hat jemand eine Idee?
Christian W. schrieb: > Hat jemand eine Idee? Er sah den Wald vor lauter Bäumen nicht und wusste daher nicht das Pi schon vorkonserviert zur Verfügung steht.
Christian W. schrieb: > Hallo zusammen, ich bin neulich über ein Codeschnipsel in einem großen > Programm gestolpert. Dort wird die Kreiszahl Pi in einer etwa 15 Zeilen > langen Funktion berechnet, obwohl in der selben Datei die <math.h> > eingebunden ist, und somit der Zugriff auf "M_PI" möglich wäre. Die > Funktion liefert als Rückgabetyp einen "long double". Genauer als 20 > Stellen wird's ja deswegen auch nicht, oder? Was ist der Sinn der Sache, > dass der Programmierer Pi in einer Funktion berechnet, anstatt auf die > definierte Konstante mit 20 Nachkommastellen zuzugreifen? Ich bin nicht > dahintergekommen. Hat jemand eine Idee? ich schreibe immer "pi = (4 * arctan(-1))", sieht irgendwie viel cooler aus als das benutzen einer Konstanten aus math.h :-) Micha
Ich tippe mal auf mangelnde Kenntnisse der Standard-Bibliothek... :-)
Profilierung vor der Freundin? Das kann man so nicht sagen. Kommt drauf an, ob er mit einem long double die Auflösung und die Genauigkeit überhaupt noch ausfahren kann. Ohne Analyse dessen, wie damit gerechnet wird und wie die Fehlerfortpflanzung zuschlägt, ist dazu wenig zu sagen. Mal ganz davon abgesehen, dass es recht witzlos ist, das jedes mal neu zu rechnen. Wenn schon, dann bestimmt man sich PI auf die Anzahl der Stellen die man haben will oder lädt die sich aus dem Web runter. Noch ein #define und gut ists.
:
Bearbeitet durch User
Christian W. schrieb: > Dort wird die Kreiszahl Pi in einer etwa 15 Zeilen langen > Funktion berechnet, obwohl in der selben Datei die <math.h> > eingebunden ist, und somit der Zugriff auf "M_PI" möglich wäre. M_PI wird in math.h auch nicht definiert. M_PI ist eine GNU-Erweiterung, d.h. es kann verwendet werden und wird durch math.h verfügbar wenn die Quelle in GNU-C steht. "Offiziell" ist M_PI aber nicht. > Die Funktion liefert als Rückgabetyp einen "long double". > Genauer als 20 Stellen wird's ja deswegen auch nicht, oder? > Was ist der Sinn der Sache, dass der Programmierer Pi in einer > Funktion berechnet, anstatt auf die definierte Konstante > mit 20 Nachkommastellen zuzugreifen? Wenn man den Algorithmus nicht sorgsam auwählt, ist die Näherung vermutlich deutlich schlechter als 20 Nachkommastellen und nicht besser als 22/7 oder 355/113. > Ich bin nicht dahintergekommen. Hat jemand eine Idee? Vermutlich weil der Autor Spaß dran hat. Micha S. schrieb: > ich schreibe immer "pi = (4 * arctan(-1))", sieht irgendwie viel > cooler aus als ... Dafür auch viel falscher, nämlich um 2π daneben ;-)
Johann L. schrieb: > Micha S. schrieb: >> ich schreibe immer "pi = (4 * arctan(-1))", sieht irgendwie viel >> cooler aus als ... > > Dafür auch viel falscher, nämlich um 2π daneben ;-) wer hat das -1 da hingemacht? Sauerei! :-)
Micha S. schrieb: > Johann L. schrieb: > >> Micha S. schrieb: >>> ich schreibe immer "pi = (4 * arctan(-1))", sieht irgendwie viel >>> cooler aus als ... >> >> Dafür auch viel falscher, nämlich um 2π daneben ;-) > > wer hat das -1 da hingemacht? Sauerei! :-) alte Regel: immer eine gerade Anzahl an Vorzeichenfehlern machen!
1 | pi = -( 4 * atan(-1) ); |
:-)
Ok, danke für die schnellen und zahlreichen Antworten. Fassen wir mal zusammen. Ich kann also generell am Anfang meiner C-Datei oder in meiner selbst erstellten Headerdatei schreiben:
1 | #define MY_PI 3.14159265358979323846
|
...und kann überall da, wo im Programm die Pi-Berechnungs-Funktion aufgerufen wird, diese durch "MY_PI" ersetzen, ohne dass sich an der Genauigkeit des Ergebnisses (3 Nachkommastellen sind gefordert) etwas ändert. Richtig? Vor allem bei Mikrocontroller-Anwendungen bei einem Takt von 1 MHz finde ich generell ein #define besser als eine Berechnungsfunktion für Pi, beispielsweise aus Zeitgründen... Christian.
Christian W. schrieb: > Hallo zusammen, ich bin neulich über ein Codeschnipsel in einem großen > Programm gestolpert. Dort wird die Kreiszahl Pi in einer etwa 15 Zeilen > langen Funktion berechnet, obwohl in der selben Datei die <math.h> > eingebunden ist, und somit der Zugriff auf "M_PI" möglich wäre. Die > Funktion liefert als Rückgabetyp einen "long double". Genauer als 20 > Stellen wird's ja deswegen auch nicht, oder? Doch es könnte genauer werden. Die Floating point units rechnen intern mit einer höheren Genauigkeit als die "integer" Einheit. So definiert der Standard IEEE-754 eine 32 bit genauigkeit und eine extended 40 bit. Bei Datenaustausch muss jeweils gerundet werden. Es könnte also sein das bei den define-pi das schliesslich im assemblercode über die integer einheit in die floating point einheit geladen wird nur 32 bit übergeben werden können, während bei der Berechnungsroutine 40 bit genau ermittelt wird. http://en.wikipedia.org/wiki/Extended_precision#IEEE_754_extended_precision_formats http://c-faq.com/fp/strangefp.html Zitat: " Beware that some machines have more precision available in floating-point computation registers than in double values stored in memory" MfG,
Christian W. schrieb: > Fassen wir mal zusammen. > > Ich kann also generell am Anfang meiner C-Datei oder in meiner selbst > erstellten Headerdatei schreiben: > >
1 | #define MY_PI 3.14159265358979323846
|
> > ...und kann überall da, wo im Programm die Pi-Berechnungs-Funktion > aufgerufen wird, diese durch "MY_PI" ersetzen, ohne dass sich an der > Genauigkeit des Ergebnisses (3 Nachkommastellen sind gefordert) etwas > ändert. Richtig? Nein, siehe Antwort eins drüber.
Aha, langsam kommt Licht in's Dunkel. Heißt das also, dass ein Präprozessor-Define immer nur 32-Bit-genau ist? Die Frage ist jetzt nur, wenn ich zwar in einer Funktion Pi berechne, dann aber den Wert über den Rückgabetyp long double zurückgebe und irgendwo anders verrechne, ist die Genauigkeit dann nicht auch wieder den Bach runter? Christian
Christian W. schrieb: > Heißt das also, dass ein Präprozessor-Define immer nur 32-Bit-genau ist? ein Define ist ein Text nicht mehr und nicht weniger.
Heißt das also, dass ein Präprozessor-Define immer nur 32-Bit-genau ist? nein der preprozessor macht nur eine testuelle ersetzung, das heist er ersetzt jeden vorkommen von MY_PI durch 3.14159265358979323846. Die umwandlung in float/double macht dann der compiler
Fpga Kuechle schrieb: > Doch es könnte genauer werden. > Die Floating point units rechnen intern mit einer höheren Genauigkeit > als die "integer" Einheit. Mit Betonung auf könnte Wenm Compiler für float / double erzeugen kommt es durchaus vor, daß ihm die float-Register ausgehen und er float-Werte (temporär) in nicht-FPU Registern oder auf dem Stack zwischenlagern muss. Dann hängt die erreichte Genauigkeit von Faktoren ab wie Optimierungsgrad oder vom umgebenden Code, der scheinbar nix mit der eigentlichen Berechnung zu tun hat.
Johann L. schrieb: > Dann hängt die erreichte Genauigkeit von Faktoren ab wie > Optimierungsgrad oder vom umgebenden Code, der scheinbar nix mit der > eigentlichen Berechnung zu tun hat. das ist sogar eine extra Option vom Compiler. Im Standard sollte es so rechnen das das Ergebnis mit double nachvollziehbar ist. (also etwas ungenauer als es sein könnte) http://christian-seiler.de/projekte/fpmath/
Christian W. schrieb: > Aha, langsam kommt Licht in's Dunkel. > > Heißt das also, dass ein Präprozessor-Define immer nur 32-Bit-genau ist? "immer" ist immer falsch ;-) Also m.E. kann man die Fragen nach der besten Implementierung nur anhand der Hardware klären. Deshalb zwei Schnipsel aus dem Datenblatt zu einem der Urväter der Fliesskommaberechnung - der 8087 FPU. Früher sah die Hardwarearchitektur mal so aus RAM <-> CPU <-> FPU Die FPU (80x87)rechnet intern mit 80 bit (Schnipsel 1) die CPU kann aber nur 64 bit rüberreichen (Schnipsel 2, Op-code) -> will man also die höchste Genauigkeit muss man Pi auf der FPU berechnen und kann es nicht als Konstante rüberreichen. Das gestattet der Befehlssatz (Assembler) der CPU nicht. Damit ist es egal ob man nun in C, Pascal etc. rechnet - es geht nicht. Das erklärt erstmal warum in dem von Dir erwähenten C-Code Pi berechnet wird. Schaut man sich die FPU-register genauer an fällt weiterauf, das die nicht beliebig zugreiffbar sind, sondern als Stack orientiert sind. Man kann also das berechnete PI nicht auf Dauer auf einer fixen Addresse speichern. Das würde erklären warum Pi immer neu berechnet wird. Bei anderen Controllern wie bspw ARM-Cortex-M4 mit FPU-Option kann das wieder anders aussehen. Beim angesprochenen ARM sind FPU-Register wie "normale" Register 32 bit breit. Da bringt berechnen statt Konstante kein Plus an Genauigkeit - ARM kann an dieser Stelle wohl nicht besser als 32bit Fliesskomma. Interessant finde ich dann wieder späterer intel FPU#s, die bringen einen Befehl mit der PI mit der maximalen genauigkeit bereitstellt (FLDPI). Pi ist dabei: S = 0.f * 2^2 mit: f = C90FDAA2 2168C234 C Wie man aber dem C-Compiler sagt, das er dieses Feature im Assemblercode nutzt (wenn das Target das unterstützt) ist noch unklar. Aber wahrscheinlich nicht in dem man ein define mit möglichst vielen Stellen benutzt. MfG, *http://www.ece.usu.edu/ece_store/spec/8087.pdf - Datenblatt 8087 *http://home.agh.edu.pl/~amrozek/x87.pdf Datenblatt x87 bei IA32 S.23
Fpga Kuechle schrieb: > Wie man aber dem C-Compiler sagt, das er dieses Feature im Assemblercode > nutzt (wenn das Target das unterstützt) ist noch unklar. Seit C99 gibt es auch hexadezimale Gleitkommakonstanten. Der Sinn ist dabei, dass man auf diese Weise eine Gleitkommazahl mit einem definierten, 1:1 vergleichbaren Bitmuster festlegen kann. Für irrationale Zahlen wird aber auch das nicht helfen, sie exakt abzubilden. ;-)
Jörg Wunsch schrieb: > Seit C99 gibt es auch hexadezimale Gleitkommakonstanten. Der Sinn > ist dabei, dass man auf diese Weise eine Gleitkommazahl mit einem > definierten, 1:1 vergleichbaren Bitmuster festlegen kann. > > Für irrationale Zahlen wird aber auch das nicht helfen, sie /exakt/ > abzubilden. ;-) Nicht nur aus diesem Grund scheint mir die Variante Pi über Arkustangens zu deklarien von Vorteil. Das wurde oben auch vorgeschlagen und bei Recherchen zu Pi und C stößt man auch öfters auf diesen Vorschlag. Darüber könnte man auch eine intrinsic function basteln anhand derer der Compiler erkennt was er zu assemblieren hat, hier also den Befehl die Konstante PI zu laden. *http://de.wikipedia.org/wiki/Intrinsische_Funktion MfG, BTW: Da die FPU bei intel zu SSE mutiert ist, muß man hinsichtlich optimalet float-programmierung heutzutage nach SSE suchen?
Fpga Kuechle schrieb: > Wie man aber dem C-Compiler sagt, das er dieses Feature im Assemblercode > nutzt (wenn das Target das unterstützt) ist noch unklar. Aber > wahrscheinlich nicht in dem man ein define mit möglichst vielen Stellen > benutzt. Warum sollte es nicht? Das ist doch eine ziemlich einfache Optimierung für den Compiler.
Fpga Kuechle schrieb: > Nicht nur aus diesem Grund scheint mir die Variante Pi über Arkustangens > zu deklarien von Vorteil. und was lässt sich über die Genauigkeit des so errechneten PI sagen?
Dirk B. schrieb: > Fpga Kuechle schrieb: >> Wie man aber dem C-Compiler sagt, das er dieses Feature im Assemblercode >> nutzt (wenn das Target das unterstützt) ist noch unklar. Aber >> wahrscheinlich nicht in dem man ein define mit möglichst vielen Stellen >> benutzt. > > Warum sollte es nicht? > Das ist doch eine ziemlich einfache Optimierung für den Compiler. Woran soll der Compiler erkennen das man hier Pi wie für die FPU meint und nicht eine Näherung für Pi? Oder irgendeinen Skalierungsfaktor der nur so aussieht wie PI. also bspw bei #define M_PI 3,141526536 den FPUbefehl und bei #define M_PI 3,14152653 oder #define M_PI 3,1415265358 nicht? abgesehen von anderen schreibweisen wie 0,31415926536 * 10; Exakt wäre eine Konstante wie oben genannt: S = 0.f * 2^2 mit: f = C90FDAA2 2168C234 C Also für den Programmierer ist es sicher nicht einfacher wenn er erst Pi auf 20+ Stellen nachschauen und exakt eintippern muß um damit den gewünschten assembler-befehl zu erzeugen. Ob eine einzelne Inline-Assembler Zeile das Problem lösen kann ist auch zu bezweifeln, da es sich bei der hier beispielhaft verwandten FPU um eine mit Registerstack handelt, wo übliche calling conventions versagen. MfG,
Fpga Kuechle schrieb: > also bspw bei > #define M_PI 3,141526536 Nur zur Richtigstellung: Du meinst hier den Dezimalpunkt, nicht das Komma. P.S. Wie wärs mit PI auf 800 Stellen?
1 | int a=10000,b,c=2800,d,e,f[2801],g;main(){for(;b-c;)f[b++]=a/5; |
2 | for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)for(b=c;d+=f[b]*a, |
3 | f[b]=d%--g,d/=g--,--b;d*=b);} |
Walter schrieb: > Fpga Kuechle schrieb: >> Nicht nur aus diesem Grund scheint mir die Variante Pi über Arkustangens >> zu deklarien von Vorteil. > > und was lässt sich über die Genauigkeit des so errechneten PI sagen? Es soll nicht berechnet werden sondern als Konstante eingesetzt. Also der Compiler erkennt das hier eine Konstante deklariert wird, berechnet diese und setzt die dann ein. also die deklaration const T_floatType_with_best_presision C_PI = 4.0*atan(1.0); wird nach compilieren durch das Laden des Registers/Stack mit der optimalen Konstante ersetzt. Dort wird das für FORTRAN erklärt: http://stackoverflow.com/questions/2157920/why-define-pi-4atan1 Wie das bei C genau gemacht wird ist mir unbekannt, es ist ein Rklärungsversuch warum sich im Netz immer wieder vorgeschlagen wird Pi über den arctan zu deklarieren -> weil das eben eine Möglichkeit ist eine Zahl mit unendlich vielen Stellen mit einer endlichen Anzahl von Tastaturanschlägen exakt einzutippen. Und auf einer Tastatur ohne griechische Buchstaben ;-) MfG,
Frank M. schrieb: > Fpga Kuechle schrieb: >> also bspw bei >> #define M_PI 3,141526536 > > Nur zur Richtigstellung: Du meinst hier den Dezimalpunkt, nicht das > Komma. Ja! > > P.S. > Wie wärs mit PI auf 800 Stellen? >
1 | > int a=10000,b,c=2800,d,e,f[2801],g;main(){for(;b-c;)f[b++]=a/5; |
2 | > for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)for(b=c;d+=f[b]*a, |
3 | > f[b]=d%--g,d/=g--,--b;d*=b);} |
4 | >
|
Nimm die atan-Variante, da bekommst du alle Stellen ;-). MfG,
Jörg Wunsch schrieb: > Für irrationale Zahlen wird aber auch das nicht helfen, sie /exakt/ > abzubilden. ;-) Immerhin ist es möglich, mit manchen irrationalen Zahlen exakt zu rechnen bzw. rechnen zu lassen: 1) man begnügt sich mit +, -, *, / und Kompositionen davon. 2) und die Zahl(en) sind nicht transzendent wie beispielsweise
In Indiana wurde mal ein Gesetzesentwurf vorgelegt (und beinahe auch beschlossen) dass Pi auf 3,2 festgelegt wird. http://de.wikipedia.org/wiki/Indiana_Pi_Bill Vielleicht hat er nicht gewußt dass PI nun doch auch 3.141.. bleibt.
Babbage schrieb: > In Indiana wurde mal ein Gesetzesentwurf vorgelegt (und beinahe auch > beschlossen) dass Pi auf 3,2 festgelegt wird. Wenn man auf einem Gebirgspass lebt (wo die Erdoberfläche hyperbolische Geometrie hat) ist das Verhältnis von Umfanng zu Durchmesser eines Kreises größer als 3.1415.... Wahrscheinlich wuchs der legendäre Mr. Goodwin auf einem Pass auf und hat einfach mal nachgemessen anstatt theoriegläubig Kreisumfang / Durchmesser = 3.1415... nachzubeten :-) Das Gesetz kam schlichweg deshalb nicht durch den Senat, weil die Herren Senatoren 1) vom Schulsystem indoktrinierte Ignoranten waren, die Euklids 5. Postulat als gottgegeben ansahen 2) oder in Tälern oder auf Bergen wohnten (wo das Verhältnis von Umfang zu Durchmesser eines Kreise aufgrund der dort herrschenden sphärischen Geometrie) bekanntlich kleiner als 3.1415... ist; 3) oder in den Plains aufwuchsen wo Umfang zu Durchnesser eines Kreise tatsächlich 3.1415... ist. Oder alles zusammen. Verfolgt man den Lauf der Geschichte jedoch weiter, so erkennt man, daß Mr. Goodwin einfach nur seiner Zeit voraus war: Noch keine 20 Jahre später revolutionierte ein gewisser Hr. Einstein das mathematisch-physikalische Weltbild durch eine Gravitationstheorie in Gestalt einer Geometrisierung von Raum und Zeit, nach welcher der Raum außerhalb von Himmelskörpern tatsächlich eine hyperbolische Geometrie aufweist. Wer es nicht glaubt: Nachmessen!
:
Bearbeitet durch User
Fpga Kuechle schrieb: > Früher sah die Hardwarearchitektur mal so aus > > RAM <-> CPU <-> FPU > > Die FPU (80x87)rechnet intern mit 80 bit (Schnipsel 1) > die CPU kann aber nur 64 bit rüberreichen (Schnipsel 2, Op-code) Stimmt nicht. Das Laden eines 80-Bit-Wertes ist das, was in dem von dir verlinkten (etwas verwirrenden) Dokument als "Temporary Real Memory to ST(0)" bezeichnet wird. > -> will man also die höchste Genauigkeit muss man Pi auf der FPU > berechnen und kann es nicht als Konstante rüberreichen. Das gestattet > der Befehlssatz (Assembler) der CPU nicht. Doch, tut er. Siehe z.B. http://www2.deec.uc.pt/~jlobo/tc/opcode_f.html
1 | FLD Floating point load |
2 | |
3 | operand 8087 287 387 486 Pentium |
4 | reg 17-22 17-22 14 4 1 FX |
5 | mem32 (38-56)+EA 38-56 20 3 1 FX |
6 | mem64 (40-60)+EA 40-60 25 3 1 FX |
7 | mem80 (53-65)+EA 53-65 44 6 3 NP |
Oder wenn's von Intel selbst kommen soll: "The double extended-precision format is normally reserved for holding intermediate results in the x87 FPU registers and constants. Its extra length is designed to shield final results from the effects of rounding and overflow/underflow in intermediate calculations. However, when an application requires the maximum range and precision of the x87 FPU (for data storage, computations, and results), values can be stored in memory in double extended-precision format." (*) Das 80-Bit-Format wird von gcc auch über den Typ long double unterstützt. (*) http://home.agh.edu.pl/~amrozek/x87.pdf Seite 8-17.
Fpga Kuechle schrieb: > Woran soll der Compiler erkennen das man hier Pi wie für die FPU meint > und nicht eine Näherung für Pi? Oder irgendeinen Skalierungsfaktor der > nur so aussieht wie PI. Darum: Fpga Kuechle schrieb: > in dem man ein define mit möglichst vielen Stellen benutzt.
Rolf Magnus schrieb: > Fpga Kuechle schrieb: >> Früher sah die Hardwarearchitektur mal so aus >> >> RAM <-> CPU <-> FPU >> >> Die FPU (80x87)rechnet intern mit 80 bit (Schnipsel 1) >> die CPU kann aber nur 64 bit rüberreichen (Schnipsel 2, Op-code) > > Stimmt nicht. Das Laden eines 80-Bit-Wertes ist das, was in dem von dir > verlinkten (etwas verwirrenden) Dokument als "Temporary Real Memory to > ST(0)" bezeichnet wird. > >> -> will man also die höchste Genauigkeit muss man Pi auf der FPU >> berechnen und kann es nicht als Konstante rüberreichen. Das gestattet >> der Befehlssatz (Assembler) der CPU nicht. > > Doch, tut er. Siehe z.B. > http://www2.deec.uc.pt/~jlobo/tc/opcode_f.html >
1 | > FLD Floating point load |
2 | > |
3 | > operand 8087 287 387 486 Pentium |
4 | > reg 17-22 17-22 14 4 1 FX |
5 | > mem32 (38-56)+EA 38-56 20 3 1 FX |
6 | > mem64 (40-60)+EA 40-60 25 3 1 FX |
7 | > mem80 (53-65)+EA 53-65 44 6 3 NP |
8 | > |
Sicher? Also das intel-paper bezieht sich auf 80X87 der IA32 Architektur, also 32bit processoren. Der 8087 ist der Co vom 8086 als 16bit. In dem PNG-Schnipsel des Instructions set wird gezeigt das ganze zwei bit benutzt werden um die Operandenbreite zu codieren (Bitfeld M)? und da sind keine 80 bit vorgesehen. Und das PNG ist auch von intel. Ich stimme zu, das ist verwirrend, ich bin mir da auch nicht 100% sicher, halte aber den Auszug des Instructions-code für ein sehr starkes Argumenten gegen die These das es bei diesem Co-Prozessor 80 bit Zugriffe auf die FPU gibt. Und der 8087 ist hier nur beispielhaft gemeint. Das bis jetzt noch nicht näher beschriebene Code-schnipsel des TO kann auch für eine andere machine gedacht sein (DSP, ibm360, space-ASIC) bei der die interne Darstellung höhere Genauigkeit aufweist als mit dem Speicher austauschbar ist. Vielleicht gibt es eine solche Maschine auch nicht aber der Code würde die maximal verfügbare Genauigkeit ausnutzen. MfG,
Dirk B. schrieb: > Fpga Kuechle schrieb: >> Woran soll der Compiler erkennen das man hier Pi wie für die FPU meint >> und nicht eine Näherung für Pi? Oder irgendeinen Skalierungsfaktor der >> nur so aussieht wie PI. > > Darum: > Fpga Kuechle schrieb: >> in dem man ein define mit möglichst vielen Stellen benutzt. ?Also in der Spec für den compiler soll stehen" "Wenn Sie möglichst viele Stellen für Pi im define verwenden wird die FPU-interne Konstante genutzt, wenn mindestens eine stelle weniger als möglichst dann diese." ? Das ist dann aber scherzhaft gemeint, oder? Und wenn man bei den beispielwhaft 200 Stellen sich an einer vertippt ... Also da muss eine eindeutige Notation verwendet werden. So wie wenn man ein Drittel möchte auch "ein Drittel" sagt/notiert oder "1/3" und nicht 0.33333333333333333... . Wenn man Pi möchte dann sollte man auch pi verlangen und keine gekürzte Variante. MfG
>Für irrationale Zahlen wird aber auch das nicht helfen, sie exakt >abzubilden. ;-) Chuck Norris kann das. Er kennt alle Stellen von PI!
Fpga Kuechle schrieb: > Sicher? Ich hab's noch nicht selbst ausprobiert, aber ich hab extra noch eins von meinen alten verstaubten x86-Assembler-Büchern aus dem Regal gezogen, und da wird das bestätigt. Darin findet sich eine ähnliche Tabelle mit Taktzyklen für die Instruktion ab 8087. Ich kann mich auch noch aus dem Turbo Assembler an die Datentypen BYTE, WORD, DWORD, QWORD und TBYTE erinnern. Letzterer war eben der 80-Bit-Datentyp. > Also das intel-paper bezieht sich auf 80X87 der IA32 Architektur, > also 32bit processoren. Der 8087 ist der Co vom 8086 als 16bit. In dem > PNG-Schnipsel des Instructions set wird gezeigt das ganze zwei bit > benutzt werden um die Operandenbreite zu codieren (Bitfeld M)? und da > sind keine 80 bit vorgesehen. Das gilt aber nur für die Variante "Integer/Real Memory to ST(0)". Die 80-Bit-Instruktion ist wie schon geschrieben die separate Variante "Temporary Real Memory to ST(0)". Die hat auch den gleichen Opcode wie der in meinem Buch angegebene 80-Bit-Speicherzugriff. Ich vermute, daß das "Temporary" hier darauf anspielt, daß die Instruktion wie in dem von mir verlinkten Dokument eher dafür gedacht ist, um Zwischenergebnisse mit vollen 80 Bit auch in den Speicher schreiben zu können. > Und der 8087 ist hier nur beispielhaft gemeint. Das bis jetzt noch nicht > näher beschriebene Code-schnipsel des TO kann auch für eine andere > machine gedacht sein (DSP, ibm360, space-ASIC) bei der die interne > Darstellung höhere Genauigkeit aufweist als mit dem Speicher austauschbar > ist. Ich fand's erstaunlich, jetzt zu lesen, daß man mit Absicht intern mit größerer Bitbreite rechnet als man nachher extern üblicherweise verwendet, damit Zwischenergebnisse genauer sind. In C will man das nicht unbedingt immer, weil das Verhalten dann nicht der Spezifikation entspricht. Man spricht in so einem Fall von "excess presicion". Deshalb gibt es die oben schon mal von jemandem erwähne Möglichkeit, den Compiler zu zwingen, jedes Zwischenergebnis erst in den Speicher zu schreiben und wieder von da zu lesen, um die Größe auf diese Weise auf 32 oder 64 Bit zu reduzieren. Das macht die Sache zwar tierisch lahm, aber sorgt dafür, dass das Verhalten dann der Vorgabe von ISO-C entspricht.
Seit dem 14. März 1988 feiern Mathematik-Freunde in aller Welt den Tag der Kreiszahl. Aufgrund der amerikanischen Datumsschreibweise 3-14-15 gerät er in diesem Jahr zum Super-Pi-Tag. Heise...
Rolf Magnus schrieb: > Fpga Kuechle schrieb: >> Sicher? > > Ich hab's noch nicht selbst ausprobiert, aber ich hab extra noch eins > von meinen alten verstaubten x86-Assembler-Büchern aus dem Regal > gezogen, und da wird das bestätigt. OK, da habe ich mich geirrt, "80 bit laden" ist wohl möglich. Ich hab mal aus meinen Regal auch mal des vergilbteste Lehrbuch gezogen - "Einführung in die 16bit-Mikrorechentechnik mit dem K1860 WM 86" Militärverlag 1988. Der K1810WM86 ist ein "Sowjetischer" kompatibler Nachbau zum intel 8086, WM87 der zum 8087. Das 80 bit Format heisst dort "Gleitkomma nicht normalisiert (temporäres Format)" und es gibt 3 Ladebefehle für float: FLD GK kurz 11011001 FLD GK lang 11011101 FLD GK temporar 11011011 //den hab ich übersehen Und es werden auch Konstantenladebefehle erwähnt, aber nicht welche Genauigkeit damit realisiert wird: FLDZ Null FLD1 Eins FLDPI Pi FLDL2T Log2 10 > Ich fand's erstaunlich, jetzt zu lesen, daß man mit Absicht intern mit > größerer Bitbreite rechnet als man nachher extern üblicherweise > verwendet, damit Zwischenergebnisse genauer sind. Das hat mich wiederum nicht überrascht. Meine antrainierte Erwartungshaltung bei Hand- und Maschinenrechnung ist das immer die gültigen Stellen angegeben werden - sind weniger Stellen gültig gibt man (bei Handrechnung) die ungültigen nicht an (Beisp Einkaufspreis, 5.99 € und nicht 5.9900000€. Hat man nun eine fixe Stellenanzahl die immer ausgegeben werden muß bspw. Mantisse 52 bit dann müssen die oberen 51 Stellen genau sein, die letzte gerundet. Deshalb genauere Zwischenergebnisse. > In C will man das > nicht unbedingt immer, weil das Verhalten dann nicht der Spezifikation > entspricht. OK, das ist mir Bitzähler neu, ich bin da eher auf der Seite derer die eine garantierte Genauigkeit wollen. Dazu gibt es recht interessante Abhandlungen von William Kahn - der mathematiker der intel bei floating point beraten hat: http://en.wikipedia.org/wiki/Rounding#The_table-maker.27s_dilemma MfG,
Damit kein falscher Eindruck entsteht sei noch daran erinnert, dass die Anzahl Bits, mit der auf PCs mit Fliesskommawerten bei Zwischenwerten durchschnittlich gerechnet wird, mittlerweile immer geringer wird, also die Ergebnisse im Gesamtmittel immer ungenauer werden. In 16- und 32-Bit Zeiten rechnete man, wie hier ausgiebig beschrieben, bei Zwischenwerten meist im 80 Bit Format des 8087 Koprozessors und dessen internen Nachfahren. Seit zunehmend 64-Bit Programme eingesetzt werden entfällt dieses 80-Bit Zwischenformat. Denn das 64-Bit Programmiermodell der üblichen Betriebssysteme sieht an Stelle des x87 Befehlssatzes SSE vor. Und da steht auch für Zwischenwerte nur das 64-Bit Format zur Verfügung.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.