-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathfloat.xml
More file actions
196 lines (169 loc) · 9.86 KB
/
float.xml
File metadata and controls
196 lines (169 loc) · 9.86 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
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: e587d0655e426f97b3fcb431453da5030e743b23 Maintainer: shein Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.types.float" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Числа с плавающей точкой</title>
<para>
Числа с плавающей запятой в руководстве называются «числами с плавающей точкой»,
поскольку в английском языке — языке оригинала PHP-руководства — целую и дробную часть в таких числах
разделяет точка, а не запятая. В других языках программирования числа с плавающей точкой называют также:
float, double или real. В PHP числа с плавающей точкой записывают следующими синтаксисами:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // Начиная с PHP 7.4.0
?>
]]>
</programlisting>
</informalexample>
<para>
Поддержка подчёркиваний в числах появилась с PHP 7.4.0:
</para>
<informalexample>
<programlisting>
<![CDATA[
LNUM [0-9]+(_[0-9]+)*
DNUM ({LNUM}?"."{LNUM}) | ({LNUM}"."{LNUM}?)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
]]>
</programlisting>
</informalexample>
<para>
Размер числа с плавающей точкой зависит от платформы, хотя максимум обычного значения с плавающей точкой
составляет примерно 1.8e308 с точностью около 14 десятичных цифр (64-битный формат стандарта IEEE).
</para>
<warning xml:id="warn.float-precision">
<title>Точность чисел с плавающей точкой</title>
<para>
Точность чисел с плавающей точкой ограничена. Хотя точность
зависит от операционной системы, PHP обычно использует формат
двойной точности, который определяет стандарт IEEE 754, который даёт
максимальную относительную погрешность округления порядка 1.11e-16.
Неэлементарные арифметические операции иногда дают бо́льшие ошибки,
и, конечно, учитывают распространение ошибок при объединении операции.
</para>
<para>
Кроме того, рациональные числа наподобие <literal>0.1</literal>
или <literal>0.7</literal>, которые легко точно представить
как числа с плавающей точкой по основанию 10 — в десятичной системе счисления,
внутренне невозможно точно представить как числа с плавающей точкой по основанию 2 — в двоичной системе счисления,
независимо от размера мантиссы. Поэтому такие числа невозможно преобразовать во внутреннюю двоичную форму
без небольшой потери точности. Иногда это даёт противоречивые результаты:
например, округление <literal>floor((0.1 + 0.7) * 10)</literal> возвращает
значение <literal>7</literal> вместо <literal>8</literal>, которое ожидалось, поскольку
внутреннее представление будет примерно таким:
<literal>7.9999999999999991118...</literal>.
</para>
<para>
Точности чисел с плавающей точкой не доверяют до последней цифры
и не сравнивают такие числа на предмет равенства.
Когда требуется повышенная точность, пользуются
<link linkend="ref.bc">функциями математики произвольной точности</link>
и <link linkend="ref.gmp">функциями математики множественной точности модуля GMP</link>.
</para>
<para>
«Простое» объяснение даёт <link xlink:href="&url.floating.point.guide;">руководство по числам с плавающей точкой</link>,
которое также называется «Why don’t my numbers add up?» («Почему мои числа не складываются?» — англ.)
</para>
</warning>
<sect2 xml:id="language.types.float.casting">
<title>Преобразование в число с плавающей точкой</title>
<sect3 xml:id="language.types.float.casting.from-string">
<title>Из строк</title>
<simpara>
<link linkend="language.types.numeric-strings">Числовые строки</link>
или строки с начальной числовой последовательностью преобразовываются в значение с плавающей точкой,
иначе строка преобразуется в целочисленное значение <literal>0</literal>.
</simpara>
</sect3>
<sect3 xml:id="language.types.float.casting.from-other">
<title>Из других типов</title>
<para>
При преобразовании значений других типов в число с плавающей точкой значение вначале преобразовывается в целое число (<type>int</type>),
а затем в число с плавающей точкой (<type>float</type>).
Дополнительную информацию о целочисленном преобразовании даёт раздел «<link linkend="language.types.integer.casting">Преобразование в целое число</link>».
</para>
<note>
<para>
Поскольку поведение отдельных типов при преобразовании в тип <type>int</type>, то же самое происходит и при преобразовании в
число с плавающей точкой (<type>float</type>).
</para>
</note>
</sect3>
</sect2>
<sect2 xml:id="language.types.float.comparison">
<title>Сравнение чисел с плавающей точкой</title>
<para>
Как отмечалось в предыдущем предупреждении, проверка чисел с плавающей точкой на равенство
даёт сомнительные результаты из-за ограничений внутреннего представления таких чисел,
однако PHP поддерживает способы сравнения чисел с плавающей точкой,
которые обходят эти ограничения.
</para>
<para>
Для сравнения чисел с плавающей точкой используется верхняя граница
относительной ошибки при округлении. Эта величина называется
машинной эпсилон или единицей округления (unit roundoff)
и представляет собой самую маленькую допустимую разницу при расчётах.
</para>
<para>
Числа <varname>$a</varname> и <varname>$b</varname> равны до 5-ти
знаков после точки.
</para>
<example>
<title>Сравнение чисел с плавающей точкой</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>
Некоторые числовые операции могут возвращать значение, представляемое
константой <constant>NAN</constant>. Данный результат означает неопределённое
или непредставимое значение в операциях с плавающей точкой. Любое строгое
или нестрогое сравнение данного значения с другим значением, кроме &true;, включая его
самого, возвратит &false;.
</para>
<para>
Так как <constant>NAN</constant> представляет собой неограниченное количество
различных значений, то <constant>NAN</constant> не следует сравнивать с
другими значениями, включая её саму. Вместо этого, для определения её наличия
необходимо использовать функцию <function>is_nan</function>.
</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
-->