with round reducir redondeo redondear number_format los hacia enteros decimals decimales con cifras arriba aproximar php decimal rounding

round - reducir los decimales en php



PHP bajando decimales sin redondear (10)

Las respuestas de RenaPot , IsisCode , goredwards no son correctas.

Debido a cómo funciona float en las computadoras (en general), float no es exacto.

Para replicar el problema:

floor(19.99 * 100);// Outputs 1998 instead of 1999 floor(19.99 * 100);// Outputs 509 instead of 510

Dentro de PHP internamente, 19.99 * 100 resulta en algo así como 1998.999999999999999 , que cuando hacemos floor de eso, obtenemos 1998 .

Solución:

Solución 1: use la biblioteca bcmath (sugerida por @SamyMassoud) si la tiene instalada (es posible que algunos servidores de alojamiento compartido no la tengan instalada de manera predeterminada). Al igual que:

//floor(19.99 * 100);// Original floor(bcmul(19.99, 100));// Outputs 1999

Solución 2: manipulación de cuerdas (mi recomendación):

// Works with positive and negative numbers, and integers and floats and strings function withoutRounding($number, $total_decimals) { $number = (string)$number; if($number === '''') { $number = ''0''; } if(strpos($number, ''.'') === false) { $number .= ''.''; } $number_arr = explode(''.'', $number); $decimals = substr($number_arr[1], 0, $total_decimals); if($decimals === false) { $decimals = ''0''; } $return = ''''; if($total_decimals == 0) { $return = $number_arr[0]; } else { if(strlen($decimals) < $total_decimals) { $decimals = str_pad($decimals, $total_decimals, ''0'', STR_PAD_RIGHT); } $return = $number_arr[0] . ''.'' . $decimals; } return $return; } // How to use: withoutRounding(19.99, 2);// Return "19.99" withoutRounding(1.505, 2);// Return "1.50" withoutRounding(5.1, 2);// Return "5.10"

Quiero dejar decimales sin redondear. Por ejemplo, si tengo 1.505, quiero soltar el último decimal y el valor debería ser 1.50. ¿Existe tal función en PHP?


Necesitas floor() de esta manera:

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

O lo conviertes en entero:

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

De esta manera no se redondeará.


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

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 de esto es que floor() siempre redondea el número hacia abajo , no hacia cero.
es decir, floor() redondea efectivamente los números -ve hacia un valor absoluto mayor
por ejemplo, floor(1.5) = 1 mientras que floor(-1.5) = -2

Por lo tanto, para la multiply by power, remove decimals, divide by power método de truncado de multiply by power, remove decimals, divide by power :
- floor() solo funciona para números positivos
- ceil() solo funciona para 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>''; ?>


Podemos usar funciones bc si están disponibles:

echo bcadd(sprintf(''%F'', 5.445), ''0'', 2); // => 5.44 echo sprintf(''%.2F'', 5.445); // => 5.45


Sé que esta es una respuesta tardía pero aquí hay una solución simple. Usando el ejemplo OP de 1.505, simplemente puede 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 administra valores tanto positivos como negativos sin la preocupación de filtrar qué función usar y presta para corregir resultados sin preocuparse 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 es necesario para obtener exactamente 2 decimales para mostrar, de lo contrario, el Resultado habría sido 1.5 en lugar de 1.50.


Tal vez sea demasiado tarde, pero aquí hay 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 usar una Expresión Regular (que a veces podría 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.


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


solo haz (int) $number; para obtener entero


$float = 1.505; echo sprintf("%.2f", $float); //outputs 1.50


$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 redondearlo.