-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathfloat.xml
More file actions
202 lines (178 loc) · 6.56 KB
/
float.xml
File metadata and controls
202 lines (178 loc) · 6.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: e587d0655e426f97b3fcb431453da5030e743b23 Maintainer: simp Status: ready -->
<!-- Reviewed: yes -->
<!-- Rev-Revision: d494ffa4d9f83b60fe66972ec2c0cf0301513b4a Reviewer: samesch -->
<sect1 xml:id="language.types.float" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Gleitkommazahlen</title>
<para>
Gleitkommazahlen (auch als "floats", "doubles" oder "reelle Zahlen"
bezeichnet) können anhand einer der folgenden Schreibweisen bezeichnet
werden:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // von PHP 7.4.0 an
?>
]]>
</programlisting>
</informalexample>
<para>
Formell von PHP 7.4.0 an (zuvor waren Unterstriche nicht erlaubt):
</para>
<informalexample>
<programlisting>
<![CDATA[
LNUM [0-9]+(_[0-9]+)*
DNUM ({LNUM}?"."{LNUM}) | ({LNUM}"."{LNUM}?)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
]]>
</programlisting>
</informalexample>
<para>
Die Größe einer Gleitkommazahl ist plattformabhängig, ein Maximalwert von
circa 1.8e308 mit einer Präzision von ungefähr 14 Dezimal-Nachkommastellen
ist jedoch ein üblicher Wert (64-Bit IEEE-Format).
</para>
<warning xml:id="warn.float-precision">
<title>Genauigkeit von Gleitkommazahlen</title>
<para>
Gleitkommazahlen haben eine begrenzte Präzision. Obgleich dies vom System
abhängig ist, verwendet PHP üblicherweise das IEEE 754 Double Precision
Format, welches einen maximalen relativen Rundungsfehler in einer
Größenordnung en 1.11e-16 ergibt. Nicht-Elementare arithmetische
Operationen können jedoch größere Fehler hervorrufen und natürlich muss
eine Fortpflanzung des Fehlers berücksichtigt werden, wenn mehrere
Operationen zusammengesetzt werden.
</para>
<para>
Außerdem gibt es rationale Zahlen, die zur Basis 10 als Gleitkommazahlen
exakt dargestellt werden können, beispielsweise <literal>0.1</literal> oder
<literal>0.7</literal>, für die es aber keine exakte Repräsentation als
Gleitkommazahlen zur Basis 2 gibt, welche intern aber unabhängig von der
Größe der Mantisse verwendet wird. Daher können sie nicht ohne einen
geringen Präzisionsverlust in ihre interne binäre Darstellung umgewandelt
werden. Dies kann zu verwirrenden Ergebnissen führen:
<literal>floor((0.1+0.7)*10)</literal> wird üblicherweise
<literal>7</literal> ergeben statt des erwarteten Ergebnisses von
<literal>8</literal>, da die interne Repräsentation etwas ist wie
<literal>7.9999999999999991118...</literal>.
</para>
<para>
Man sollte sich daher niemals bis zur letzten Nachkommastelle auf
Gleitkommazahlen verlassen und Gleitkommazahlen niemals direkt auf
Gleichheit prüfen. Wenn eine höhere Präzision notwendig ist, stehen die
<link linkend="ref.bc">Mathematikfunktionen mit beliebiger Präzision</link>
und die <link linkend="ref.gmp">gmp</link>-Funktionen zur Verfügung.
</para>
<para>
Für eine "einfache" Erklärung steht der Ratgeber
<link xlink:href="&url.floating.point.guide;">Floating Point Guide</link>
zur Verfügung, welcher auch den Titel hat "Why don’t my numbers add up?"
</para>
</warning>
<sect2 xml:id="language.types.float.casting">
<title>Umwandlung in float</title>
<sect3 xml:id="language.types.float.casting.from-string">
<title>Von Strings</title>
<simpara>
Wenn der String
<link linkend="language.types.numeric-strings">numerisch</link> ist oder
numerisch beginnt, wird er in den entsprechenden Gleitkommawert
umgewandelt, andernfalls wird er in Null (<literal>0</literal>)
umgewandelt.
</simpara>
</sect3>
<sect3 xml:id="language.types.float.casting.from-other">
<title>Von anderen Typen</title>
<para>
Werte aller anderen Typen werden umgewandelt, indem die Werte zuerst in den
Typ <type>int</type> umgewandelt werden und dieser anschließend zu
<type>float</type>. Weitere Informationen findet man unter
<link linkend="language.types.integer.casting">Umwandlung in Integer</link>.
</para>
<note>
<para>
Da bestimmte Typen ein undefiniertes Verhalten bei der Umwandlung in
<type>int</type> haben, ist dies auch bei der Umwandlung in
<type>float</type> der Fall.
</para>
</note>
</sect3>
</sect2>
<sect2 xml:id="language.types.float.comparison">
<title>Gleitkommazahlen vergleichen</title>
<para>
Wie in der obigen Warnung bereits dargestellt, ist es problematisch,
Gleitkommazahlen auf Gleichheit zu überprüfen, aufgrund ihrer internen
Darstellungsart. Es gibt allerdings Wege, diese Vergleiche von
Gleitkommazahlen anzustellen, die diese Beschränkungen umgehen.
</para>
<para>
Um Gleitkommazahlen auf Gleichheit zu prüfen, wird eine obere Schranke für
den Rundungsfehler verwendet. Dieser Wert ist bekannt als
Maschinengenauigkeit Epsilon und stellt die kleinste annehmbare Differenz
in der Berechnung dar.
</para>
<para>
<varname>$a</varname> und <varname>$b</varname> sind bis auf 5
Nachkommastellen gleich.
</para>
<example>
<title>Vergleichen von Gleitkommazahlen</title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;
if (abs($a - $b) < $epsilon) {
echo "true";
}
?>
]]>
</programlisting>
</example>
</sect2>
<sect2 xml:id="language.types.float.nan">
<title>NaN</title>
<para>
Einige numerische Operationen können einen Wert ergeben, der durch die
Konstante <constant>NAN</constant> dargestellt wird. Dieses Ergebnis
stellt einen undefinierten oder nicht darstellbaren Wert in den
Fließkommaberechnungen dar. Jeder strikte oder nicht strikte Vergleich
dieses Werts mit jedem beliebigen anderen Wert, inklusive sich selbst, nur
nicht &true;, wird ein Ergebnis von &false; hervorbringen.
</para>
<para>
Da <constant>NAN</constant> eine beliebige Anzahl von anderen Werten
darstellen kann, sollte <constant>NAN</constant> nicht mit anderen Werten,
einschließlich sich selbst, verglichen werden. Stattdessen sollte zur
Prüfung <function>is_nan</function> verwendet werden.
</para>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->