2012-01-31 149 views

Respuesta

31

Es necesario floor() de esta manera:

$rounded = floor($float*100)/100; 

O lanzas a un entero:

$rounded = 0.01 * (int)($float*100); 

De esta manera no será redondeando hacia arriba.

+0

funciona bien a menos que el 0 se arrastra en el ejemplo es un requerimiento. – Leigh

+0

@Leigh: Resuelto [en esta respuesta] (http://stackoverflow.com/a/9079258/367456). – hakre

+1

Para valores negativos, el uso ceil() en lugar de suelo() –

2

puede convertir 1.505 al tipo de datos Cadena y hacer uso de substring() para truncar el último carácter.
Y vuelva a convertirlo en integer.

+1

¿Qué sucede si el número es 1 dígito más largo después de la coma? –

+0

¿Al menos leíste lo que OP quiere? – Legionar

13
$float = 1.505; 

echo sprintf("%.2f", $float); 

//outputs 1.50 
+1

+1, simple y dulce. – hakre

+0

Funciona muy bien cuando se combina con la conversión de tipo '(flotante) $ flotante' si continúa utilizando esto en los cálculos. –

+8

Es importante tener en cuenta que 'sprintf' ROUND flota si cree que es necesario. Por ejemplo, tomemos la división '31/53 = 0,584905 [...]' - si queremos 3 cifras decimales, podemos hacer 'sprintf ("% 3F", (31/53))' pero esto no da nosotros 0.584. Nos da 0.585. –

0

Eso sí, (int) $number; para conseguir número entero

+0

¿Al menos leíste lo que OP quiere? – Legionar

3

Tal vez sea demasiado tarde, pero aquí es un buen enfoque:

$getTruncatedValue = function($value, $precision) 
    { 
     //Casts provided value 
     $value = (string)$value; 

     //Gets pattern matches 
     preg_match("/(-+)?\d+(\.\d{1,".$precision."})?/" , $value, $matches); 

     //Returns the full pattern match 
     return $matches[0];    
    }; 

    var_dump 
    (
     $getTruncatedValue(1.123,1), //string(3) "1.1" 
     $getTruncatedValue(1.345,2), //string(4) "1.34" 
     $getTruncatedValue(1.678,3), //string(5) "1.678" 
     $getTruncatedValue(1.90123,4) //string(6) "1.9012" 
    ); 
  • El único escollo en este enfoque puede ser la necesidad de utilizar una Expresión regular (que a veces puede traer una penalización de rendimiento).

Nota: es bastante difícil encontrar un enfoque nativo para truncar decimales, y creo que no es posible realizar eso usando sprintf y otras funciones relacionadas con cadenas.

+1

Gracias, quiero probar este. – reignsly

3

Para hacer esto con precisión para ambos + ve y números -ve necesita usar:
- la función de php para floor() + ve números
- la función php ceil() para los números -ve

function truncate_float($number, $decimals) { 
    $power = pow(10, $decimals); 
    if($number > 0){ 
     return floor($number * $power)/$power; 
    } else { 
     return ceil($number * $power)/$power; 
    } 
} 

la razón para esto es que floor() siempre redondea el número abajo, no hacia cero.
es decir floor() rondas eficazmente números -ve hacia un valor absoluto mayor
por ejemplo floor(1.5) = 1 mientras floor(-1.5) = -2

Por lo tanto, para el método de multiply by power, remove decimals, divide by power truncado:
- floor() sólo funciona para números positivos
- ceil() sólo funciona para los números negativos

Para probar esto, copie el siguiente código en el editor de http://phpfiddle.org/lite (o similar):

<div>Php Truncate Function</div> 
<br> 
<?php 
    function truncate_float($number, $places) { 
     $power = pow(10, $places); 
     if($number > 0){ 
      return floor($number * $power)/$power; 
     } else { 
      return ceil($number * $power)/$power; 
     } 
    } 

    // demo 
    $lat = 52.4884; 
    $lng = -1.88651; 
    $lat_tr = truncate_float($lat, 3); 
    $lng_tr = truncate_float($lng, 3); 
    echo 'lat = ' . $lat . '<br>'; 
    echo 'lat truncated = ' . $lat_tr . '<br>'; 
    echo 'lat = ' . $lng . '<br>'; 
    echo 'lat truncated = ' . $lng_tr . '<br><br>'; 

    // demo of floor() on negatives 
    echo 'floor (1.5) = ' . floor(1.5) . '<br>'; 
    echo 'floor (-1.5) = ' . floor(-1.5) . '<br>'; 
?> 
0

Sé que esta es una respuesta tardía, pero aquí hay una solución simple. Usando el ejemplo de OP de 1.505, puede simplemente usar lo siguiente para llegar a 1.50.

function truncateExtraDecimals($val, $precision) { 
    $pow = pow(10, $precision); 
    $precise = (int)($val * $pow); 
    return (float)($precise/$pow); 
} 

Esto logra valores positivos y negativos sin la preocupación de filtro que funciona a utilizar y se presta para corregir los resultados sin tener que preocuparse acerca de qué otras funciones podrían hacer con el valor.

$val = 1.509; 
$truncated = sprintf('%.2f', truncateExtraDecimals($val, 2)); 
echo "Result: {$truncated}"; 

Result: 1.50 

El sprintf se necesita para obtener exactamente 2 decimales para mostrar lo contrario, el resultado habría sido de 1,5 en lugar de 1,50.

0

podemos utilizar funciones bc si están disponibles:

echo bcadd(sprintf('%F', 5.445), '0', 2); // => 5.44 
echo sprintf('%.2F', 5.445); // => 5.45 
0
$num = 118.74999669307; 
$cut = substr($num, 0, ((strpos($num, '.')+1)+2));` 
// Cut the string from first character to a length of 2 past the decimal. 
/substr(cut what, start, ((find position of decimal)+decimal itself)+spaces after decimal)) 
echo $cut; 

Esto le ayudará a acortar el valor flotante sin redondeo ella ..

Cuestiones relacionadas