PHP cadere decimali senza arrotondamenti

Voglio lasciare decimali senza arrotondamenti. Per esempio se ho 1.505, voglio far cadere ultimo decimale e il valore deve essere di 1,50 euro. C’è una funzione in PHP?

InformationsquelleAutor newbie | 2012-01-31

 

10 Replies
  1. 37

    È necessario piano() in questo modo:

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

    O cast per intero:

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

    In questo modo non sarà arrotondamento.

    • Funziona bene, a meno che il finale 0 nell’esempio è un requisito.
    • Per i valori negativi, utilizzare ceil() invece di pavimento()
    • questa non è una soluzione completa a MENO che non si solo sono numeri positivi – è necessario utilizzare floor() e ceil() se non si conosce il segno del numero che si sta arrotondamento vedere questa risposta
    • Questo non è assolutamente corretta soluzione. floor(5.1*100)/100; rendimenti 5.09, invece del previsto 5.10. Si può provare con 5.100, o 4.1 lo stesso risultato non corretto.
    • Come @MuhammedM. ha detto, non esattamente il lavoro per tutto il tempo, come in questo caso: floor(19.99 * 100) restituisce 1998 invece di 1999. Questo non dovrebbe essere la risposta corretta
    • Non ha funzionato correttamente per dire di input esempio: 2581.68. Restituisce “2581.67”, prevede tuttavia il valore di ritorno è “2581.68”.

  2. 11
    $float = 1.505;
    
    echo sprintf("%.2f", $float);
    
    //outputs 1.50
    • Funziona a meraviglia, quando combinato con typecasting (float) $float se stai continuando ad usare questo nei calcoli.
    • È importante notare che sprintf ROTONDO galleggia se lo ritiene necessario. Per esempio, prendiamo la divisione 31 / 53 = 0.584905[...] – se si desidera 3 cifre decimali, siamo in grado di fare sprintf("%.3f", (31 / 53)) ma questo NON ci dà 0.584. Ci dà p0.585.
    • sprintf arrotonda il valore… sprintf(‘%.2f’, ‘1.239’) => 1.24
    • È prevista, senza arrotondamento… 5.555 dovrebbe essere 5.55 non. 5.56
    • Questa non è la risposta. sprintf fa il giro del valore.
  3. 4

    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 in questo approccio può essere la necessità di utilizzare un’Espressione Regolare (che a volte può portare a una riduzione delle prestazioni).

    Nota: e ‘ molto difficile trovare un nativo di approccio al troncamento dei decimali, e penso che non sia possibile eseguire utilizzando sprintf e altre funzioni relative alle stringhe.

    • Grazie, voglio provare questo.
  4. 3

    Per fare questo in modo accurato per entrambi +ve e -ve numeri è necessario utilizzare:

    – php floor() funzione per +ve numeri

    – php ceil() funzione per i cinque numeri

    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() sempre arrotonda il numero giù, non verso lo zero.

    ie floor() efficacemente round -ve numeri verso una più grande in valore assoluto

    ad esempio floor(1.5) = 1 mentre floor(-1.5) = -2

    Pertanto, per il multiply by power, remove decimals, divide by power metodo truncate :

    floor() funziona solo per i numeri positivi

    ceil() funziona solo per i numeri negativi

    Per eseguire questo test, copiare e incollare il seguente codice nell’editor di http://phpfiddle.org/lite (o simili):

    <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>';
    ?>
    • Ottima soluzione!
  5. 2

    è possibile convertire 1.505 di dati di tipo Stringa e fare uso di substring() per troncare ultimo carattere.


    E di nuovo la conversione in integer.

    • che cosa succede se il numero è 1 cifra dopo la virgola?
  6. 2
    $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à a ridurre il valore decimale senza arrotondamento è..

    • La sua mi ha preso un bel po ‘ a trovare questa risposta, sembra molto promettente come la soluzione!!!
  7. 2

    Le risposte di RenaPot, IsisCode, goredwards non sono corrette.

    A causa di come galleggiante funziona nel computer (in generale), float non è preciso.

    Per replicare il problema:

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

    PHP internamente, 19.99 * 100 risultati in qualcosa di simile a 1998.999999999999999, che quando noi floor di che, si ottiene 1998.

    Soluzione:

    Soluzione 1: Utilizzare bcmath biblioteca (Suggerito da @SamyMassoud) se si è installato (alcuni di hosting condiviso, server potrebbero non avete installato per impostazione predefinita). In questo modo:

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

    Soluzione 2: la manipolazione di stringhe (il mio consiglio):

    //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"
  8. 0

    So che questo è un ritardo di risposta, ma qui è una soluzione semplice. Utilizzando l’OP esempio di 1.505, si può semplicemente utilizzare il seguente per ottenere a 1,50.

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

    Questo gestisce sia i valori positivi e negativi, senza la preoccupazione di filtro che funzione, l’uso e si presta a risultati corretti, senza preoccuparsi di ciò che le altre funzioni potrebbe fare con il valore.

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

    La sprintf è necessario per ottenere esattamente 2 cifre decimali da visualizzare altrimenti il Risultato sarebbe stato di 1,5 invece di 1.50.

  9. 0

    Possiamo usare bc funzioni se sono disponibili:

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

    basta fare (int) $number; per ottenere un numero intero

    • Questa potrebbe essere una buona soluzione se si vuole scendere tutti i decimali.

Lascia un commento