mirror of
https://github.com/php/doc-zh.git
synced 2026-03-24 07:02:15 +01:00
166 lines
5.3 KiB
XML
166 lines
5.3 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- $Revision$ -->
|
||
<!-- EN-Revision: e587d0655e426f97b3fcb431453da5030e743b23 Maintainer: Avenger Status: ready -->
|
||
<!-- CREDITS: Gregory, dallas, Altair, Luffy -->
|
||
<sect1 xml:id="language.types.float" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||
<title>Float 浮点型</title>
|
||
|
||
<para>
|
||
浮点型(也叫浮点数 float,双精度数 double 或实数 real)可以用以下任一语法定义:
|
||
</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>,无论有多少尾数都不能被内部所使用的二进制精确表示,因此不能在不丢失一点点精度的情况下转换为二进制的格式。这就会造成混乱的结果:例如,<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>网页的简单解释。
|
||
</para>
|
||
</warning>
|
||
|
||
<sect2 xml:id="language.types.float.casting">
|
||
<title>转换为浮点数</title>
|
||
|
||
<sect3 xml:id="language.types.float.casting.from-string">
|
||
<title>从 string 转换</title>
|
||
|
||
<simpara>
|
||
如果 string 是 <link linkend="language.types.numeric-strings">numeric</link> 或者前导数字,
|
||
则将它解析为相应的 float 值,否则将转换为零(<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>
|
||
如上述警告信息所言,由于内部表达方式的原因,比较两个浮点数是否相等是有问题的。不过还是有迂回的方法来比较浮点数值的。
|
||
</para>
|
||
|
||
<para>
|
||
要测试浮点数是否相等,要使用一个仅比该数值大一丁点的最小误差值。该值也被称为机器极小值(epsilon)或最小单元取整数,是计算中所能接受的最小的差别值。
|
||
</para>
|
||
|
||
<para>
|
||
<varname>$a</varname> 和 <varname>$b</varname> 在小数点后五位精度内都是相等的。
|
||
</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
|
||
-->
|