<?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 => 'es',
  ),
  'this' => 
  array (
    0 => 'random-randomizer.getfloat.php',
    1 => 'Random\\Randomizer::getFloat',
    2 => 'Devuelve un float seleccionado 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' => 'es',
    '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">Devuelve un float seleccionado uniformemente</span></p>

 </div>

 <div class="refsect1 description" id="refsect1-random-randomizer.getfloat-description">
  <h3 class="title">Descripción</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">
   Devuelve un float seleccionado uniformemente y equidistribuido de un intervalo solicitado.
  </p>
  <p class="para">
   Debido a la precisión limitada, no todos los números reales pueden ser
   representados exactamente como floats.

   Si un número no puede ser representado exactamente, se redondea al número
   exactamente representable más cercano.

   Además, los floats no son igualmente densos en toda la línea de números.

   Debido a que los floats utilizan un exponente binario, la distancia entre dos
   floats vecinos se duplica en cada potencia de dos.

   En otras palabras: Hay el mismo número de floats representables entre
   <code class="literal">1.0</code> y <code class="literal">2.0</code>
   que entre
   <code class="literal">2.0</code> y <code class="literal">4.0</code>,
   <code class="literal">4.0</code> y <code class="literal">8.0</code>,
   <code class="literal">8.0</code> y <code class="literal">16.0</code>,
   y así sucesivamente.
  </p>
  <p class="para">
   Seleccionar un número aleatorio en un intervalo arbitrario, por ejemplo
   dividiendo dos enteros, podría resultar en una distribución sesgada por esta razón.

   El redondeo necesario hará que algunos floats sean devueltos con más frecuencia que
   otros, en particular alrededor de las potencias de dos cuando la densidad de los floats
   cambia.
  </p>
  <p class="para">
   <span class="methodname"><strong>Random\Randomizer::getFloat()</strong></span> implementa un algoritmo que
   devolverá un float seleccionado uniformemente del conjunto más grande posible
   de floats exactamente representables y equidistribuidos en el intervalo solicitado.

   La distancia entre los floats seleccionables (« paso ») corresponde a la distancia
   entre los floats con la densidad más baja, es decir, la distancia entre los
   floats en los límites del intervalo con el valor absoluto más grande.

   Esto significa que no todos los floats representables en un intervalo dado pueden
   ser devueltos si el intervalo cruza una o más potencias de dos.

   El paso comenzará en el límite del intervalo con el valor absoluto más grande
   para garantizar que los pasos se alineen con los floats exactamente representables.
  </p>
  <p class="para">
   Los límites de intervalo cerrados siempre estarán incluidos en el conjunto de floats
   seleccionables.

   Por lo tanto, si el tamaño del intervalo no es un múltiplo exacto del paso y el límite
   con el valor absoluto más pequeño es un límite cerrado, la distancia entre este límite
   y su float más cercano será más pequeña que el paso.
  </p>
  <div class="caution"><strong class="caution">Precaución</strong>
   <p class="para">
    El postprocesamiento de los floats devueltos corre el riesgo de romper la equidistribución uniforme,
    ya que los floats intermedios en una operación matemática sufren un redondeo implícito.

    El intervalo solicitado debe corresponder lo más estrechamente posible al intervalo deseado
    y el redondeo solo debe realizarse como una operación explícita justo antes
    de mostrar el número seleccionado a un usuario.
   </p>
  </div>
  <div class="refsect2 unknown-28" id="refsect2-random-randomizer.getfloat-unknown-28">
   <h4 class="title">Explicaciones del algoritmo utilizando valores de ejemplo</h4>
   <p class="para">
    Para dar un ejemplo del funcionamiento del algoritmo, consideremos una representación
    en coma flotante que utiliza una mantisa de 3 bits.

    Esto es capaz de representar 8 valores float
    diferentes entre las potencias de dos consecutivas.

    Esto significa que entre
    <code class="literal">1.0</code> y <code class="literal">2.0</code> todos los pasos de tamaño <code class="literal">0.125</code>
    son exactamente representables y entre <code class="literal">2.0</code> y <code class="literal">4.0</code>
    todos los pasos de tamaño <code class="literal">0.25</code> son exactamente representables.

    En realidad, los floats de PHP utilizan una mantisa de 52 bits y pueden representar
    2<sup class="superscript">52</sup> valores diferentes entre cada potencia de dos.

    Esto 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>
    son los floats exactamente representables entre
    <code class="literal">1.0</code> y <code class="literal">4.0</code>.
   </p>
   <p class="para">
    Ahora consideremos que <code class="code">$randomizer-&gt;getFloat(1.625, 2.5, IntervalBoundary::ClosedOpen)</code>
    es llamado, es decir, que se solicita un float aleatorio comenzando en <code class="literal">1.625</code> hasta,
    pero sin incluir, <code class="literal">2.5</code>.

    El algoritmo determina primero el paso en el límite con el valor absoluto más grande
    (<code class="literal">2.5</code>). El paso en este límite es <code class="literal">0.25</code>.
   </p>
   <p class="para">
    Es de notar que el tamaño del intervalo solicitado es <code class="literal">0.875</code>, que no es
    un múltiplo exacto de <code class="literal">0.25</code>.

    Si el algoritmo comenzara a caminar en el límite inferior <code class="literal">1.625</code>, encontraría
    <code class="literal">2.125</code>, que no es exactamente representable y sufriría
    un redondeo implícito.

    Por lo tanto, el algoritmo comienza a caminar en el límite superior <code class="literal">2.5</code>.

    Los valores seleccionables son:
    <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> no está incluido, ya que el límite superior del intervalo solicitado
    es un límite abierto.

    <code class="literal">1.625</code> está incluido, incluso si su distancia al valor más cercano
    <code class="literal">1.75</code> es <code class="literal">0.125</code>, que es más pequeña que el paso
    determinado previamente de <code class="literal">0.25</code>.

    La razón por la que es así es que el intervalo solicitado está cerrado en el límite
    inferior (<code class="literal">1.625</code>) y los límites cerrados siempre están incluidos.
   </p>
   <p class="para">
    Finalmente, el algoritmo selecciona uniformemente uno de los cuatro valores seleccionables
    al azar y lo devuelve.
   </p>
   <div class="refsect3 unknown-31" id="random-randomizer.getfloat.affine-transformation">
    <h5 class="title">Por qué dividir dos enteros no funciona</h5>
    <p class="para">
     En el ejemplo anterior, hay ocho números float representables
     entre cada subintervalo delimitado por una potencia de dos.

     Para dar un ejemplo de por qué dividir dos enteros no funcionaría bien
     para generar un float aleatorio, consideremos que hay 16 números float
     uniformemente distribuidos en el intervalo abierto a la derecha de <code class="literal">0.0</code>
     hasta, pero sin incluir, <code class="literal">1.0</code>. La mitad de ellos son los
     ocho valores exactamente representables entre <code class="literal">0.5</code> y <code class="literal">1.0</code>,
     la otra mitad son los valores entre <code class="literal">0.0</code> y <code class="literal">1.0</code>
     con un paso de <code class="literal">0.0625</code>.

     Estos valores pueden generarse fácilmente dividiendo un entero aleatorio entre
     <code class="literal">0</code> y <code class="literal">15</code> por <code class="literal">16</code> para obtener
     uno de los siguientes valores:

     <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 aleatorio podría escalarse al intervalo abierto a la derecha
     de <code class="literal">1.625</code> hasta, pero sin incluir, <code class="literal">2.75</code> multiplicándolo por el tamaño
     del intervalo (<code class="literal">0.875</code>) y añadiendo el mínimo <code class="literal">1.625</code>.
     Esta transformación afín daría los siguientes valores:

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

     Es de notar cómo el límite superior de <code class="literal">2.5</code> sería devuelto,
     a pesar del hecho de que sea un límite abierto y por lo tanto excluido.

     También es de notar cómo <code class="literal">2.0</code> y <code class="literal">2.25</code> tienen el doble de
     probabilidades de ser devueltos en comparación con los otros 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">
       El límite inferior del intervalo.
      </p>
     </dd>
    
    
     <dt><code class="parameter">max</code></dt>
     <dd>
      <p class="para">
       El límite superior del intervalo.
      </p>
     </dd>
    
    
     <dt><code class="parameter">boundary</code></dt>
     <dd>
      <p class="para">
       Especifica si los límites del intervalo son valores de retorno posibles.
      </p>
     </dd>
    
   </dl>
  </p>
 </div>


 <div class="refsect1 returnvalues" id="refsect1-random-randomizer.getfloat-returnvalues">
  <h3 class="title">Valores devueltos</h3>
  <p class="para">
   Un valor float seleccionado uniformemente y equidistribuido del intervalo especificado por
   <code class="parameter">min</code>, <code class="parameter">max</code> y <code class="parameter">boundary</code>.

   Si <code class="parameter">boundary</code> es <strong><code>Random\IntervalBoundary::ClosedClosed</code></strong>,
   <code class="parameter">min</code> y <code class="parameter">max</code> son valores de retorno posibles.
  </p>
 </div>


 <div class="refsect1 errors" id="refsect1-random-randomizer.getfloat-errors">
  <h3 class="title">Errores/Excepciones</h3>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     Si el valor de <code class="parameter">min</code> no es finito (<span class="function"><a href="function.is-finite.php" class="function">is_finite()</a></span>),
     se lanzará una <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Si el valor de <code class="parameter">max</code> no es finito (<span class="function"><a href="function.is-finite.php" class="function">is_finite()</a></span>),
     se lanzará una <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Si el intervalo solicitado no contiene ningún valor,
     se lanzará una <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>.
    </span>
   </li>
   
 <li class="listitem">
  <span class="simpara">
   Cualquier <span class="classname"><a href="class.throwable.php" class="classname">Throwable</a></span> lanzado por el método <span class="methodname"><a href="random-engine.generate.php" class="methodname">Random\Engine::generate()</a></span>
   del <a href="class.random-randomizer.php#random-randomizer.props.engine" class="link"><code class="literal">Random\Randomizer::$engine</code></a> subyacente.
  </span>
 </li>

  </ul>
 </div>


 <div class="refsect1 examples" id="refsect1-random-randomizer.getfloat-examples">
  <h3 class="title">Ejemplos</h3>
  <div class="example" id="example-1">
   <p><strong>Ejemplo #1 Ejemplo 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">// Es de notar que la granularidad de la latitud es el doble<br />// de la granularidad de la longitud.<br />//<br />// Para la latitud, el valor puede ser tanto -90 como 90.<br />// Para la longitud, el valor puede ser 180, pero no -180, ya que<br />// -180 y 180 se refieren a la misma longitud.<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>Resultado del ejemplo anterior es similar 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 el algoritmo de la sección γ tal como se publicó en
    <a href="https://dl.acm.org/doi/10.1145/3503512" class="link external">&raquo;&nbsp;
     Dibujar números float aleatorios de un intervalo.
     Frédéric Goual
    </a>
    para obtener las propiedades de comportamiento deseadas.
   </p>
  </p></blockquote>
  <div class="caution"><strong class="caution">Precaución</strong>
   <p class="para">
    El underflow se deja intencionalmente sin manejar en el algoritmo de sección γ.
    Esto puede resultar en valores incorrectos para intervalos con
    límites en el rango subnormal de números de punto flotante, es decir,
    para límites con un valor absoluto menor que aproximadamente
    <code class="literal">2<sup class="superscript">-1020</sup></code> (alrededor de <code class="literal">8.9e-308</code>).
   </p>
  </div>
 </div>


 <div class="refsect1 seealso" id="refsect1-random-randomizer.getfloat-seealso">
  <h3 class="title">Ver también</h3>
  <ul class="simplelist">
   <li><span class="methodname"><a href="random-randomizer.nextfloat.php" class="methodname" rel="rdfs-seeAlso">Random\Randomizer::nextFloat()</a> - Devuelve un float seleccionado del intervalo abierto a la derecha [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> - Obtener un entero seleccionado uniformemente</span></li>
  </ul>
 </div>


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