Voglio eliminare i decimali senza arrotondare. Ad esempio, se ho 1.505, voglio eliminare l'ultimo decimale e il valore dovrebbe essere 1.50. Esiste una funzione in PHP?decimali in calo di PHP senza arrotondamento
risposta
È necessario floor() in questo modo:
$rounded = floor($float*100)/100;
Oppure si lanci a intero:
$rounded = 0.01 * (int)($float*100);
In questo modo non sarà arrotondamento.
è possibile convertire 1.505
in tipo di dati String e utilizzare substring()
per troncare l'ultimo carattere.
E di nuovo convertirlo in integer
.
cosa succede se il numero è più lungo di 1 cifra dopo la virgola? –
Hai letto almeno, quale OP vuole? – Legionar
$float = 1.505;
echo sprintf("%.2f", $float);
//outputs 1.50
+1, semplice e dolce. – hakre
Funziona magnificamente se combinato con typecasting '(float) $ float' se continui a utilizzarlo nei calcoli. –
È importante notare che 'sprintf' ROUND galleggia se pensa che sia necessario. Ad esempio, prendi la divisione '31/53 = 0.584905 [...]' - se vogliamo 3 cifre decimali, possiamo fare 'sprintf ("%. 3f ", (31/53))' ma questo NON dà noi 0,584. Ci dà 0.585. –
Forse è troppo tardi, ma qui è un buon approccio:
$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"
);
- L'unica insidia di questo approccio può essere la necessità di utilizzare un Espressione regolare (che a volte potrebbe comportare una penalizzazione delle prestazioni).
Nota: È piuttosto difficile trovare un approccio nativo per troncare i decimali e penso che non sia possibile eseguirlo utilizzando sprintf e altre funzioni relative alle stringhe.
Grazie, voglio provare questo. – reignsly
Per fare questo in modo accurato per entrambi + ve e numeri -ve è necessario utilizzare:
- la funzione php floor()
per + ve numeri
- la funzione PHP ceil()
per i numeri -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 ragione di questo è che floor()
arrotonda sempre il numero giù, non a zero.
cioè floor()
arrotonda efficacemente numeri -ve verso un grande valore assoluto
es floor(1.5) = 1
mentre floor(-1.5) = -2
Pertanto, per il metodo multiply by power, remove decimals, divide by power
troncamento:
- floor()
funziona solo per i numeri positivi
- ceil()
funziona solo per numeri negativi
Per verificarlo, copiare il seguente codice nell'editor di http://phpfiddle.org/lite (o simile):
<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>';
?>
So che questa è una risposta tardiva, ma qui è una soluzione semplice. Usando l'esempio OP di 1.505 puoi semplicemente usare quanto segue per arrivare a 1.50.
function truncateExtraDecimals($val, $precision) {
$pow = pow(10, $precision);
$precise = (int)($val * $pow);
return (float)($precise/$pow);
}
Questo gestisce entrambi i valori positivi e negativi, senza la preoccupazione di filtro che funzione da utilizzare e si presta per correggere i risultati senza la preoccupazione di ciò che altre funzioni potrebbero fare con il valore.
$val = 1.509;
$truncated = sprintf('%.2f', truncateExtraDecimals($val, 2));
echo "Result: {$truncated}";
Result: 1.50
Lo sprintf è necessario per ottenere esattamente 2 decimali per visualizzare altrimenti il risultato sarebbe stato di 1,5 invece di 1,50.
possiamo usare le funzioni bc se sono disponibili:
echo bcadd(sprintf('%F', 5.445), '0', 2); // => 5.44
echo sprintf('%.2F', 5.445); // => 5.45
$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;
questo vi aiuterà abbreviare il valore float senza arrotondamento esso ..
funziona bene a meno che il finale 0 nell'esempio è Un requisito. – Leigh
@Leigh: risolto [in questa risposta] (http://stackoverflow.com/a/9079258/367456). – hakre
Per i valori negativi, utilizzare ceil() invece di floor() –