<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/class.random-randomizer.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'random-randomizer.getfloat.php',
    1 => 'Random\\Randomizer::getFloat',
    2 => 'Obt&eacute;m um float selecionado uniformemente',
  ),
  'up' => 
  array (
    0 => 'class.random-randomizer.php',
    1 => 'Random\\Randomizer',
  ),
  'prev' => 
  array (
    0 => 'random-randomizer.getbytesfromstring.php',
    1 => 'Random\\Randomizer::getBytesFromString',
  ),
  'next' => 
  array (
    0 => 'random-randomizer.getint.php',
    1 => 'Random\\Randomizer::getInt',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    'path' => 'reference/random/random/randomizer/getfloat.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="random-randomizer.getfloat" class="refentry">
 <div class="refnamediv">
  <h1 class="refname">Random\Randomizer::getFloat</h1>
  <p class="verinfo">(PHP 8 &gt;= 8.3.0)</p><p class="refpurpose"><span class="refname">Random\Randomizer::getFloat</span> &mdash; <span class="dc-title">Obtém um float selecionado uniformemente</span></p>

 </div>

 <div class="refsect1 description" id="refsect1-random-randomizer.getfloat-description">
  <h3 class="title">Descrição</h3>
  <div class="methodsynopsis dc-description">
   <span class="modifier">public</span> <span class="methodname"><strong>Random\Randomizer::getFloat</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.float.php" class="type float">float</a></span> <code class="parameter">$min</code></span>, <span class="methodparam"><span class="type"><a href="language.types.float.php" class="type float">float</a></span> <code class="parameter">$max</code></span>, <span class="methodparam"><span class="type"><a href="enum.random-intervalboundary.php" class="type Random\IntervalBoundary">Random\IntervalBoundary</a></span> <code class="parameter">$boundary</code><span class="initializer"> = <strong><code>Random\IntervalBoundary::ClosedOpen</code></strong></span></span>): <span class="type"><a href="language.types.float.php" class="type float">float</a></span></div>

  <p class="para rdfs-comment">
   Retorna um float uniformemente selecionado e equidistribuído de um intervalo solicitado.
  </p>
  <p class="para">
   Devido à precisão limitada, nem todos os números reais podem ser representados exatamente como
   um número de ponto flutuante.

   Se um número não puder ser representado exatamente, ele será arredondado para o
   valor exato representável mais próximo.

   Além disso, números flutuantes não são igualmente densos em toda a reta numérica.

   Como números flutuantes usam um expoente binário, a distância entre dois números flutuantes vizinhos
   dobra a cada potência de dois.

   Em outras palavras: há o mesmo número de floats representáveis ​​entre
   <code class="literal">1.0</code> e <code class="literal">2.0</code>
   como entre
   <code class="literal">2.0</code> e <code class="literal">4.0</code>,
   <code class="literal">4.0</code> e <code class="literal">8.0</code>,
   <code class="literal">8.0</code> e <code class="literal">16.0</code>,
   e assim por diante.
  </p>
  <p class="para">
   A amostragem aleatória de um número arbitrário dentro do intervalo solicitado, por exemplo,
   dividindo dois números inteiros, pode resultar em uma distribuição enviesada por esse motivo.

   O arredondamento necessário fará com que alguns números flutuantes sejam retornados com mais frequência do que
   outros, especialmente em torno de potências de dois quando a densidade de números flutuantes muda.
  </p>
  <p class="para">
   <span class="methodname"><strong>Random\Randomizer::getFloat()</strong></span> implementa um algoritmo que
   retornará um ponto flutuante selecionado uniformemente do maior conjunto possível de
   pontos flutuantes exatamente representáveis ​​e equidistribuídos dentro do intervalo solicitado.

   A distância entre os pontos flutuantes selecionáveis ​​(&quot;tamanho do passo&quot;) corresponde à distância
   entre os pontos flutuantes com a menor densidade, ou seja, a distância entre os pontos flutuantes
   no limite do intervalo com o maior valor absoluto.

   Isso significa que nem todos os pontos flutuantes representáveis ​​dentro de um determinado intervalo podem ser
   retornados se o intervalo cruzar uma ou mais potências de dois.

   O passo a passo começará a partir do limite do intervalo com o maior valor absoluto
   para garantir que os passos se alinhem com os pontos flutuantes exatamente representáveis.
  </p>
  <p class="para">
   Limites de intervalos fechados sempre serão incluídos no conjunto de floats
   selecionáveis.

   Portanto, se o tamanho do intervalo não for um múltiplo exato do tamanho do passo e
   o limite com o menor valor absoluto for um limite fechado, a distância
   entre esse limite e seu float selecionável mais próximo será menor que o
   tamanho do passo.
  </p>
  <div class="caution"><strong class="caution">Cuidado</strong>
   <p class="para">
    O pós-processamento dos floats retornados provavelmente quebrará a equidistribuição uniforme,
    porque os floats intermediários dentro de uma operação matemática
    estão passando por arredondamento implícito.

    O intervalo solicitado deve corresponder o mais próximo possível ao intervalo desejado
    e o arredondamento só deve ser realizado como uma operação explícita antes
    de exibir o número selecionado para um usuário.
   </p>
  </div>
  <div class="refsect2 unknown-28" id="refsect2-random-randomizer.getfloat-unknown-28">
   <h4 class="title">Explicação do algoritmo usando valores de exemplo</h4>
   <p class="para">
    Para exemplificar o funcionamento do algoritmo, considere uma representação de ponto flutuante
    que utiliza uma mantissa de 3 bits.

    Esta representação é capaz de representar 8 valores de ponto flutuante
    diferentes entre potências de dois consecutivas.

    Isso significa que entre
    <code class="literal">1.0</code> e <code class="literal">2.0</code> todos os passos de tamanho <code class="literal">0.125</code>
    são exatamente representáveis ​​e entre <code class="literal">2.0</code> e <code class="literal">4.0</code>
    todos os passos de tamanho <code class="literal">0.25</code> são exatamente representáveis.

    Na realidade, os floats do PHP utilizam uma mantissa de 52 bits e podem representar 2<sup class="superscript">52</sup>
    valores diferentes entre cada potência de dois.

    Isso significa que
    <ul class="simplelist">
     <li><code class="literal">1.0</code></li>
     <li><code class="literal">1.125</code></li>
     <li><code class="literal">1.25</code></li>
     <li><code class="literal">1.375</code></li>
     <li><code class="literal">1.5</code></li>
     <li><code class="literal">1.625</code></li>
     <li><code class="literal">1.75</code></li>
     <li><code class="literal">1.875</code></li>
     <li><code class="literal">2.0</code></li>
     <li><code class="literal">2.25</code></li>
     <li><code class="literal">2.5</code></li>
     <li><code class="literal">2.75</code></li>
     <li><code class="literal">3.0</code></li>
     <li><code class="literal">3.25</code></li>
     <li><code class="literal">3.5</code></li>
     <li><code class="literal">3.75</code></li>
     <li><code class="literal">4.0</code></li>
    </ul>
    são os floats exatamente representáveis ​​entre <code class="literal">1.0</code>
    e <code class="literal">4.0</code>.
   </p>
   <p class="para">
    Agora, considere que <code class="code">$randomizer-&gt;getFloat(1.625, 2.5, IntervalBoundary::ClosedOpen)</code>
    é chamado, ou seja, um float aleatório começando em <code class="literal">1.625</code> até, mas não incluindo,
    <code class="literal">2.5</code> ser solicitado.

    O algoritmo primeiro determina o tamanho do passo na fronteira com o maior valor absoluto
    (<code class="literal">2.5</code>). O tamanho do passo nessa fronteira é <code class="literal">0.25</code>.
   </p>
   <p class="para">
    Observe que o tamanho do intervalo solicitado é <code class="literal">0.875</code>, que
    não é um múltiplo exato de <code class="literal">0.25</code>.

    Se o algoritmo começasse a avançar no limite inferior <code class="literal">1.625</code>,
    encontraria <code class="literal">2.125</code>, que não é exatamente representável e
    sofreria arredondamento implícito.

    Portanto, o algoritmo começa a avançar no limite superior <code class="literal">2.5</code>.

    Os valores selecionáveis ​​são:
    <ul class="simplelist">
     <li><code class="literal">2.25</code></li>
     <li><code class="literal">2.0</code></li>
     <li><code class="literal">1.75</code></li>
     <li><code class="literal">1.625</code></li>
    </ul>

    <code class="literal">2.5</code> não está incluído, pois o limite superior do intervalo solicitado
    é um limite aberto.

    <code class="literal">1.625</code> está incluído, embora sua distância até o valor mais próximo
    <code class="literal">1.75</code> seja <code class="literal">0.125</code>, que é menor que o
    tamanho do passo previamente determinado de <code class="literal">0.25</code>.

    O motivo para isso é que o intervalo solicitado é fechado no limite inferior
    (<code class="literal">1.625</code>) e limites fechados são sempre incluídos.
   </p>
   <p class="para">
    Por fim, o algoritmo seleciona uniformemente um dos quatro valores selecionáveis ​​aleatoriamente
    e o retorna.
   </p>
   <div class="refsect3 unknown-31" id="random-randomizer.getfloat.affine-transformation">
    <h5 class="title">Por que dividir dois números inteiros não funciona</h5>
    <p class="para">
     No exemplo anterior, há oito números de ponto flutuante representáveis
     entre cada subintervalo delimitado por uma potência de dois.

     Para exemplificar por que dividir dois inteiros não funcionaria bem para gerar
     um número flutuante aleatório, considere que há 16 números de ponto flutuante equidistribuídos
     no intervalo aberto à direita de <code class="literal">0.0</code> até, mas não incluindo,
     <code class="literal">1.0</code>. Metade deles são os oito valores exatamente representáveis
     entre <code class="literal">0.5</code> e <code class="literal">1.0</code>, a outra metade são os
     valores entre <code class="literal">0.0</code> e <code class="literal">1.0</code> cujo passo
     é de <code class="literal">0.0625</code>.

     Eles podem ser facilmente gerados dividindo um número inteiro aleatório entre <code class="literal">0</code>
     e <code class="literal">15</code> por <code class="literal">16</code> para obter um dos seguintes:

     <ul class="simplelist">
      <li><code class="literal">0.0</code></li>
      <li><code class="literal">0.0625</code></li>
      <li><code class="literal">0.125</code></li>
      <li><code class="literal">0.1875</code></li>
      <li><code class="literal">0.25</code></li>
      <li><code class="literal">0.3125</code></li>
      <li><code class="literal">0.375</code></li>
      <li><code class="literal">0.4375</code></li>
      <li><code class="literal">0.5</code></li>
      <li><code class="literal">0.5625</code></li>
      <li><code class="literal">0.625</code></li>
      <li><code class="literal">0.6875</code></li>
      <li><code class="literal">0.75</code></li>
      <li><code class="literal">0.8125</code></li>
      <li><code class="literal">0.875</code></li>
      <li><code class="literal">0.9375</code></li>
     </ul>
    </p>
    <p class="para">
     Este float aleatório poderia ser escalado para o intervalo aberto à direita de <code class="literal">1.625</code>
     até, mas não incluindo, <code class="literal">2.75</code>, multiplicando-o pelo tamanho
     do intervalo (<code class="literal">0.875</code>) e adicionando o mínimo <code class="literal">1.625</code>.
     Essa chamada transformação afim resultaria nos valores:

     <ul class="simplelist">
      <li><code class="literal">1.625</code> arredondado para <code class="literal">1.625</code></li>
      <li><code class="literal">1.679</code> arredondado para <code class="literal">1.625</code></li>
      <li><code class="literal">1.734</code> arredondado para <code class="literal">1.75</code></li>
      <li><code class="literal">1.789</code> arredondado para <code class="literal">1.75</code></li>
      <li><code class="literal">1.843</code> arredondado para <code class="literal">1.875</code></li>
      <li><code class="literal">1.898</code> arredondado para <code class="literal">1.875</code></li>
      <li><code class="literal">1.953</code> arredondado para <code class="literal">2.0</code></li>
      <li><code class="literal">2.007</code> arredondado para <code class="literal">2.0</code></li>
      <li><code class="literal">2.062</code> arredondado para <code class="literal">2.0</code></li>
      <li><code class="literal">2.117</code> arredondado para <code class="literal">2.0</code></li>
      <li><code class="literal">2.171</code> arredondado para <code class="literal">2.25</code></li>
      <li><code class="literal">2.226</code> arredondado para <code class="literal">2.25</code></li>
      <li><code class="literal">2.281</code> arredondado para <code class="literal">2.25</code></li>
      <li><code class="literal">2.335</code> arredondado para <code class="literal">2.25</code></li>
      <li><code class="literal">2.390</code> arredondado para <code class="literal">2.5</code></li>
      <li><code class="literal">2.445</code> arredondado para <code class="literal">2.5</code></li>
     </ul>

     Observe como o limite superior de <code class="literal">2.5</code> seria retornado, apesar de
     ser um limite aberto e, portanto, excluído.

     Observe também como <code class="literal">2.0</code> e <code class="literal">2.25</code> têm o dobro
     de probabilidade de serem retornados em comparação com os outros valores.
    </p>
   </div>

  </div>

 </div>


 <div class="refsect1 parameters" id="refsect1-random-randomizer.getfloat-parameters">
  <h3 class="title">Parâmetros</h3>
  <p class="para">
   <dl>
    
     <dt><code class="parameter">min</code></dt>
     <dd>
      <p class="para">
       O limite inferior do intervalo.
      </p>
     </dd>
    
    
     <dt><code class="parameter">max</code></dt>
     <dd>
      <p class="para">
       O limite superior do intervalo.
      </p>
     </dd>
    
    
     <dt><code class="parameter">boundary</code></dt>
     <dd>
      <p class="para">
       Especifica se os limites do intervalo são valores de retorno possíveis.
      </p>
     </dd>
    
   </dl>
  </p>
 </div>


 <div class="refsect1 returnvalues" id="refsect1-random-randomizer.getfloat-returnvalues">
  <h3 class="title">Valor Retornado</h3>
  <p class="para">
   Um float uniformemente selecionado e equidistribuído do intervalo especificado por <code class="parameter">min</code>,
   <code class="parameter">max</code> e <code class="parameter">boundary</code>.

   Se <code class="parameter">min</code> e <code class="parameter">max</code> são valores de retorno possíveis depende
   do valor de <code class="parameter">boundary</code>.
  </p>
 </div>


 <div class="refsect1 errors" id="refsect1-random-randomizer.getfloat-errors">
  <h3 class="title">Erros/Exceções</h3>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     Se o valor de <code class="parameter">min</code> não for finito (<span class="function"><a href="function.is-finite.php" class="function">is_finite()</a></span>),
     um <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> será gerado.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Se o valor de <code class="parameter">max</code> não for finito (<span class="function"><a href="function.is-finite.php" class="function">is_finite()</a></span>),
     um <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> será lançado.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Se o intervalo solicitado não contiver nenhum valor,
     um <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span> será gerado.
    </span>
   </li>
   
 <li class="listitem">
  <span class="simpara">
   Qualquer erro ou exceção <span class="classname"><a href="class.throwable.php" class="classname">Throwable</a></span> lançados pelo método <span class="methodname"><a href="random-engine.generate.php" class="methodname">Random\Engine::generate()</a></span>
   do mecanismo <a href="class.random-randomizer.php#random-randomizer.props.engine" class="link"><code class="literal">Random\Randomizer::$engine</code></a> subjacente.
  </span>
 </li>

  </ul>
 </div>


 <div class="refsect1 examples" id="refsect1-random-randomizer.getfloat-examples">
  <h3 class="title">Exemplos</h3>
  <div class="example" id="example-1">
   <p><strong>Exemplo #1 Exemplo de <span class="methodname"><strong>Random\Randomizer::getFloat()</strong></span></strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$randomizer </span><span style="color: #007700">= new </span><span style="color: #0000BB">\Random\Randomizer</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// Observe que a granularidade da latitude é o dobro da<br />// granularidade da longitude.<br />//<br />// Para a latitude, o valor pode ser -90 e 90.<br />// Para a longitude, o valor pode ser 180, mas não -180, porque<br />// -180 e 180 referem-se à mesma longitude.<br /></span><span style="color: #0000BB">printf</span><span style="color: #007700">(<br />    </span><span style="color: #DD0000">"Lat: %+.6f Lng: %+.6f"</span><span style="color: #007700">,<br />    </span><span style="color: #0000BB">$randomizer</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getFloat</span><span style="color: #007700">(-</span><span style="color: #0000BB">90</span><span style="color: #007700">, </span><span style="color: #0000BB">90</span><span style="color: #007700">, </span><span style="color: #0000BB">\Random\IntervalBoundary</span><span style="color: #007700">::</span><span style="color: #0000BB">ClosedClosed</span><span style="color: #007700">),<br />    </span><span style="color: #0000BB">$randomizer</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getFloat</span><span style="color: #007700">(-</span><span style="color: #0000BB">180</span><span style="color: #007700">, </span><span style="color: #0000BB">180</span><span style="color: #007700">, </span><span style="color: #0000BB">\Random\IntervalBoundary</span><span style="color: #007700">::</span><span style="color: #0000BB">OpenClosed</span><span style="color: #007700">),<br />);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>O exemplo acima produzirá
algo semelhante a:</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive examplescode"><pre class="examplescode">Lat: +69.244304 Lng: -53.548951</pre>
</div>
   </div>
  </div>
 </div>


 <div class="refsect1 notes" id="refsect1-random-randomizer.getfloat-notes">
  <h3 class="title">Notas</h3>
  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <p class="para">
    Este método implementa o algoritmo de seção γ, conforme publicado em
    <a href="https://dl.acm.org/doi/10.1145/3503512" class="link external">&raquo;&nbsp;
     Drawing Random Floating-Point Numbers from an Interval.
     Frédéric Goualard, ACM Trans. Model. Comput. Simul., 32:3, 2022
    </a>
    para obter as propriedades comportamentais desejadas.
   </p>
  </p></blockquote>
  <div class="caution"><strong class="caution">Cuidado</strong>
   <p class="para">
    O underflow é intencionalmente deixado sem tratamento no algoritmo de seção γ.
    Isso pode resultar em valores incorretos sendo retornados para intervalos com
    limites na faixa subnormal de números de ponto flutuante, ou seja,
    para limites com um valor absoluto menor que aproximadamente
    <code class="literal">2<sup class="superscript">-1020</sup></code> (cerca de <code class="literal">8.9e-308</code>).
   </p>
  </div>
 </div>


 <div class="refsect1 seealso" id="refsect1-random-randomizer.getfloat-seealso">
  <h3 class="title">Veja Também</h3>
  <ul class="simplelist">
   <li><span class="methodname"><a href="random-randomizer.nextfloat.php" class="methodname" rel="rdfs-seeAlso">Random\Randomizer::nextFloat()</a> - Obt&eacute;m um float do intervalo aberto &agrave; direita [0,0, 1,0)</span></li>
   <li><span class="methodname"><a href="random-randomizer.getint.php" class="methodname" rel="rdfs-seeAlso">Random\Randomizer::getInt()</a> - Obt&eacute;m um inteiro selecionado uniformemente</span></li>
  </ul>
 </div>


</div><?php manual_footer($setup); ?>