-
Notifications
You must be signed in to change notification settings - Fork 81
Expand file tree
/
Copy pathfloat.xml
More file actions
191 lines (166 loc) · 6.93 KB
/
float.xml
File metadata and controls
191 lines (166 loc) · 6.93 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
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: e587d0655e426f97b3fcb431453da5030e743b23 Maintainer: takagi Status: ready -->
<!-- CREDITS: hirokawa,shimooka,mumumu -->
<sect1 xml:id="language.types.float" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>浮動小数点数</title>
<para>
浮動小数点数 (あるいは "float", "double", "実数") は、次の構文により指定できます。
</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>
float の大きさはプラットフォーム依存です。ただし、通常はおよそ 10
進数で 14 桁の精度があり、最大値は およそ 1.8e308 (これは 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> は、
二進数の浮動小数点数としては正確に表現できません。
これは、仮数部をいくら大きくしても同じです。
したがって、それを内部的な二進数表現に変換する際には、どうしても多少精度が落ちてしまいます。
その結果、不思議な結果を引き起こすことがあります。たとえば、
<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;">floating point guide</link>
を見るといいでしょう。"Why don’t my numbers add up? (なんで数字が足されないの?)" というタイトルが付いています。
</para>
</warning>
<sect2 xml:id="language.types.float.casting">
<title>float への変換</title>
<sect3 xml:id="language.types.float.casting.from-string">
<title>文字列から float への変換</title>
<simpara>
文字列が
<link linkend="language.types.numeric-strings">数値形式の文字列</link>
の場合、対応する float の値に解決されます。
そうでない場合、ゼロ(<literal>0</literal>)に変換されます。
</simpara>
</sect3>
<sect3 xml:id="language.types.float.casting.from-other">
<title>他の型から float への変換</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>float の比較</title>
<para>
先ほど警告したように、浮動小数点数値が等しいかどうかを比較するのには問題があります。
これは、浮動小数点数値の内部表現形式に起因するものです。
しかし、この制限を回避して浮動小数点数値の値を比較する方法もあります。
</para>
<para>
浮動小数点数値が等しいかどうかを調べるには、比較時の丸め誤差の上界を用います。
この値は計算機イプシロンあるいは丸め単位と呼ばれ、
計算時に扱える最小の差分を表します。
</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> で表される値になることがあります。
この定数は、浮動小数点演算における未定義の値あるいは表現不能な値を表します。
この値を他の値と比較すると、緩やかな比較および厳密な比較のいずれでも結果は &false; になります。
自分自身と比較した場合も含みますが、&true; と比較した場合は除きます。
</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
-->