2012-05-17 8 views
5

Ho un algoritmo che esegue i seguenti calcoli:Nessuna funzione di troncamento in PHP - Opzioni?

  1. ((0,50 * 0) + 7)/10 = 0,70
  2. ((0,70 * 10) + 9)/20 = 0,80
  3. ((0.80 * 20) + 7)/30 = ,7666,666667 millions -> voglio che questo valore per troncare a 0,76

in modo che possa alimentare il resto del calcolo come:

4a. ((0,76 * 30) + 8)/40 = 0,77

E non alimentare quando arrotondata due decimali 0,77:

4b. ((0,77 * 30) + 8)/40 = 0,77

**** Il seguente sembrano aver fallito e forzare un round fino a 0,77: ****

Il PHP sptrinf () funzione: PHP dropping decimals without rounding up

Il number_format PHP() funzione: PHP: show a number to 2 decimal places

Il piano PHP() funzione: Truncate float numbers with PHP

  • C'è un altro modo?
  • È possibile ottenere ciò che voglio (troncato a due cifre decimali) con PHP?

Si prega di assistere. Grazie molto.

UPDATE - SOLVED Ok, ora funziona grazie a dkamins e zneak. Ho usato l'approccio floor() (presumo che non stavo facendo qualcosa giusto in passato). Tuttavia, ora accade quanto segue:

ad es.

(0,86 * 30) + 9)/40 = 0,87 (dovrebbe), tuttavia dopo TRUNC it = 0.86

Come è troncando 0,87-0,86? Non ha senso. C'è un modo per farlo troncare solo se ci sono più di 2 posizioni decimali?

risolto:

$numDecPlace = strlen(substr(strrchr($newRel, "."), 1)); 
echo '<p>Test: Number of decimal places=' .$numDecPlace. '</p>'; 
if($numDecPlace > 2) { 
    $newRel = floor($newRel * 100)/100; // Truncate to 2dp. 
    echo '<p>Test: New relationship truncated is $newRel=' .$newRel. '</p>'; 
} 
+0

Risolto il mio aggiornamento. – leokennedy

+0

Dovresti controllare @Fernando Prieto [la sua risposta sotto] (http://stackoverflow.com/a/19124167/1890400). Usa un approccio basato su una stringa (sotto) che è simile alla prima parte della soluzione scelta, ma personalmente penso che potrebbe essere più efficiente e più robusto. – Byson

risposta

4

È possibile utilizzare la funzione di PHP floor insieme a qualche decimale spostando in questo modo:

floor(0.7666666667 * 100)/100; 
+3

E se lo trovi brutto, puoi creare un involucro sottile attorno ad esso: 'function trunc ($ number, $ places) {$ power = pow (10, $ places); piano di ritorno ($ numero * $ potere)/$ potere; } ' – zneak

+0

Ok, questo è troppo.Sembra che funzioni adesso (tipico). Ho usato sia il piano standard (num * 100)/100 e la funzione (grazie zneak) ed entrambi funzionano alla grande e ottengo il mio 0,76. Grazie molto. Eppure, ho un follow-up, vedi sopra :) – leokennedy

2

come su round()

<?php 
    echo round(3.4);   // 3 
    echo round(3.5);   // 4 
    echo round(3.6);   // 4 
    echo round(3.6, 0);  // 4 
    echo round(1.95583, 2); // 1.96 
    echo round(1241757, -3); // 1242000 
    echo round(5.045, 2); // 5.05 
    echo round(5.055, 2); // 5.06 
    ?> 
4

Tutte le risposte date qui intorno al num ber. Questa funzione ha funzionato per me e spero anche per te.

function truncate($number, $decimals) 
{ 
    $point_index = strrpos($number, '.'); 
    return substr($number, 0, $point_index + $decimals+ 1); 
} 

Dove $number è il numero per troncare e $decimals è il numero di cifre decimali che si desidera. Esempio:truncate(-38.59540719940386 , 6); rendimenti -38.595407

Se si desidera, consultare la documentazione substr s'!

+0

Mi piace questa funzione per vari motivi: è chiaro, facile capire come funziona esattamente, senza che avvenga una magia difficile da capire. Inoltre è abbastanza efficiente e sai al 100% che non ci saranno strani errori di arrotondamento. – Byson

+0

Questa funzione non funziona correttamente con i float in forma espotenziale ("2.5E7" per esempio ".Per i numeri in virgola mobile molto piccoli e negativi restituisce le stringhe come "-0,0000000". –

0

Ho usato avrebbe usato la funzione round() come menzionato da Kartikey. È possibile trovare maggiori informazioni qui a PHP.Net

float round (float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]]) 

Fissh

+0

Non sembra esserci una modalità per "verso zero", quindi non può essere utilizzata. – CoDEmanX

1

Per fare questo in modo accurato per entrambi + ve e numeri -ve è necessario l'uso:
- 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; 
    } 
} 

il motivo per questo è che floor() arrotonda sempre il numero in basso, non verso lo 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 troncato utilizzando multiply by power, round, then divide by power:
- floor() funziona solo per 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>'; 
?> 
Problemi correlati