2012-01-31 8 views

risposta

31

È 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.

+0

funziona bene a meno che il finale 0 nell'esempio è Un requisito. – Leigh

+0

@Leigh: risolto [in questa risposta] (http://stackoverflow.com/a/9079258/367456). – hakre

+1

Per i valori negativi, utilizzare ceil() invece di floor() –

2

è possibile convertire 1.505 in tipo di dati String e utilizzare substring() per troncare l'ultimo carattere.
E di nuovo convertirlo in integer.

+1

cosa succede se il numero è più lungo di 1 cifra dopo la virgola? –

+0

Hai letto almeno, quale OP vuole? – Legionar

13
$float = 1.505; 

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

//outputs 1.50 
+1

+1, semplice e dolce. – hakre

+0

Funziona magnificamente se combinato con typecasting '(float) $ float' se continui a utilizzarlo nei calcoli. –

+8

È 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. –

0

solo fare (int) $number; per ottenere intero

+0

Hai letto almeno, quale OP vuole? – Legionar

3

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.

+1

Grazie, voglio provare questo. – reignsly

3

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>'; 
?> 
0

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.

0

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 
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; 

questo vi aiuterà abbreviare il valore float senza arrotondamento esso ..