<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.types.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'language.types.float.php',
    1 => 'Числа с плавающей точкой',
    2 => 'Числа с плавающей точкой',
  ),
  'up' => 
  array (
    0 => 'language.types.php',
    1 => 'Типы',
  ),
  'prev' => 
  array (
    0 => 'language.types.integer.php',
    1 => 'Целые числа',
  ),
  'next' => 
  array (
    0 => 'language.types.string.php',
    1 => 'Строки',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'language/types/float.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.types.float" class="sect1">
 <h2 class="title">Числа с плавающей точкой</h2>

 <p class="para">
  Числа с плавающей запятой в руководстве называются «числами с плавающей точкой»,
  поскольку в английском языке — языке оригинала PHP-руководства — целую и дробную часть в таких числах
  разделяет точка, а не запятая. В других языках программирования числа с плавающей точкой называют также:
  float, double или real. В PHP числа с плавающей точкой записывают следующими синтаксисами:
 </p>

 <div class="informalexample">
  <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$a </span><span style="color: #007700">= </span><span style="color: #0000BB">1.234</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$b </span><span style="color: #007700">= </span><span style="color: #0000BB">1.2e3</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$c </span><span style="color: #007700">= </span><span style="color: #0000BB">7E-10</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$d </span><span style="color: #007700">= </span><span style="color: #0000BB">1_234.567</span><span style="color: #007700">; </span><span style="color: #FF8000">// Начиная с PHP 7.4.0<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>

 </div>

 <p class="para">
  Поддержка подчёркиваний в числах появилась с PHP 7.4.0:
 </p>

 <div class="informalexample">
  <div class="example-contents">
<div class="annotation-interactive cdata"><pre>
LNUM          [0-9]+(_[0-9]+)*
DNUM          ({LNUM}?&quot;.&quot;{LNUM}) | ({LNUM}&quot;.&quot;{LNUM}?)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
</pre></div>
  </div>

 </div>

 <p class="para">
  Размер числа с плавающей точкой зависит от платформы, хотя максимум обычного значения с плавающей точкой
  составляет примерно 1.8e308 с точностью около 14 десятичных цифр (64-битный формат стандарта IEEE).
 </p>

 <div class="warning"><strong class="warning">Внимание</strong>
  <h1 class="title">Точность чисел с плавающей точкой</h1>

  <p class="para">
   Точность чисел с плавающей точкой ограничена. Хотя точность
   зависит от операционной системы, PHP обычно использует формат
   двойной точности, который определяет стандарт IEEE 754, который даёт
   максимальную относительную погрешность округления порядка 1.11e-16.
   Неэлементарные арифметические операции иногда дают бо́льшие ошибки,
   и, конечно, учитывают распространение ошибок при объединении операции.
  </p>

  <p class="para">
   Кроме того, рациональные числа наподобие <code class="literal">0.1</code>
   или <code class="literal">0.7</code>, которые легко точно представить
   как числа с плавающей точкой по основанию 10 — в десятичной системе счисления,
   внутренне невозможно точно представить как числа с плавающей точкой по основанию 2 — в двоичной системе счисления,
   независимо от размера мантиссы. Поэтому такие числа невозможно преобразовать во внутреннюю двоичную форму
   без небольшой потери точности. Иногда это даёт противоречивые результаты:
   например, округление <code class="literal">floor((0.1 + 0.7) * 10)</code> возвращает
   значение <code class="literal">7</code> вместо <code class="literal">8</code>, которое ожидалось, поскольку
   внутреннее представление будет примерно таким:
   <code class="literal">7.9999999999999991118...</code>.
  </p>

  <p class="para">
   Точности чисел с плавающей точкой не доверяют до последней цифры
   и не сравнивают такие числа на предмет равенства.
   Когда требуется повышенная точность, пользуются
   <a href="ref.bc.php" class="link">функциями математики произвольной точности</a>
   и <a href="ref.gmp.php" class="link">функциями математики множественной точности модуля GMP</a>.
  </p>

  <p class="para">
   «Простое» объяснение даёт <a href="http://floating-point-gui.de/" class="link external">&raquo;&nbsp;руководство по числам с плавающей точкой</a>,
   которое также называется «Why don’t my numbers add up?» («Почему мои числа не складываются?» — англ.)
  </p>
 </div>

 <div class="sect2" id="language.types.float.casting">
  <h3 class="title">Преобразование в число с плавающей точкой</h3>

  <div class="sect3" id="language.types.float.casting.from-string">
   <h4 class="title">Из строк</h4>

   <p class="simpara">
    <a href="language.types.numeric-strings.php" class="link">Числовые строки</a>
    или строки с начальной числовой последовательностью преобразовываются в значение с плавающей точкой,
    иначе строка преобразуется в целочисленное значение <code class="literal">0</code>.
   </p>
  </div>

  <div class="sect3" id="language.types.float.casting.from-other">
   <h4 class="title">Из других типов</h4>

   <p class="para">
    При преобразовании значений других типов в число с плавающей точкой значение вначале преобразовывается в целое число (<span class="type"><a href="language.types.integer.php" class="type int">int</a></span>),
    а затем в число с плавающей точкой (<span class="type"><a href="language.types.float.php" class="type float">float</a></span>).
    Дополнительную информацию о целочисленном преобразовании даёт раздел «<a href="language.types.integer.php#language.types.integer.casting" class="link">Преобразование в целое число</a>».
   </p>

   <blockquote class="note"><p><strong class="note">Замечание</strong>: 
    <p class="para">
     Поскольку поведение отдельных типов при преобразовании в тип <span class="type"><a href="language.types.integer.php" class="type int">int</a></span>, то же самое происходит и при преобразовании в
     число с плавающей точкой (<span class="type"><a href="language.types.float.php" class="type float">float</a></span>).
    </p>
   </p></blockquote>
  </div>
 </div>

 <div class="sect2" id="language.types.float.comparison">
  <h3 class="title">Сравнение чисел с плавающей точкой</h3>

  <p class="para">
   Как отмечалось в предыдущем предупреждении, проверка чисел с плавающей точкой на равенство
   даёт сомнительные результаты из-за ограничений внутреннего представления таких чисел,
   однако PHP поддерживает способы сравнения чисел с плавающей точкой,
   которые обходят эти ограничения.
  </p>

  <p class="para">
   Для сравнения чисел с плавающей точкой используется верхняя граница
   относительной ошибки при округлении. Эта величина называется
   машинной эпсилон или единицей округления (unit roundoff)
   и представляет собой самую маленькую допустимую разницу при расчётах.
  </p>

  <p class="para">
   Числа <var class="varname">$a</var> и <var class="varname">$b</var> равны до 5-ти
   знаков после точки.
  </p>

  <div class="example" id="example-1">
   <p><strong>Пример #1 Сравнение чисел с плавающей точкой</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$a </span><span style="color: #007700">= </span><span style="color: #0000BB">1.23456789</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$b </span><span style="color: #007700">= </span><span style="color: #0000BB">1.23456780</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$epsilon </span><span style="color: #007700">= </span><span style="color: #0000BB">0.00001</span><span style="color: #007700">;<br /><br />if (</span><span style="color: #0000BB">abs</span><span style="color: #007700">(</span><span style="color: #0000BB">$a </span><span style="color: #007700">- </span><span style="color: #0000BB">$b</span><span style="color: #007700">) &lt; </span><span style="color: #0000BB">$epsilon</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"true"</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </div>

 <div class="sect2" id="language.types.float.nan">
  <h3 class="title">NaN</h3>
  <p class="para">
   Некоторые числовые операции могут возвращать значение, представляемое
   константой <strong><code><a href="math.constants.php#constant.nan">NAN</a></code></strong>. Данный результат означает неопределённое
   или непредставимое значение в операциях с плавающей точкой. Любое строгое
   или нестрогое сравнение данного значения с другим значением, кроме <strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong>, включая его
   самого, возвратит <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>.
  </p>
  <p class="para">
   Так как <strong><code><a href="math.constants.php#constant.nan">NAN</a></code></strong> представляет собой неограниченное количество
   различных значений, то <strong><code><a href="math.constants.php#constant.nan">NAN</a></code></strong> не следует сравнивать с
   другими значениями, включая её саму. Вместо этого, для определения её наличия
   необходимо использовать функцию <span class="function"><a href="function.is-nan.php" class="function">is_nan()</a></span>.
  </p>
 </div>
</div><?php manual_footer($setup); ?>