2013-06-20 33 views
14

Ciao Sto cercando di dividere due numeri interi ex: 12/13 ma ottengo sempre un intero intero 1 non un numero decimale.Come si ottiene un valore float durante la divisione di due numeri interi? (PHP)

Ho provato a digitare i valori per flottare in anticipo senza successo.

In pratica tutto quello che voglio è un risultato decimale come: 0,923 ...

$x = 12; 
$y = 13; 
echo $value = $x/$y; //Would like to see 0.923 not 1 
+2

Ottengo '0.92307692307692' quando eseguo questo –

+5

controlla il tuo php.ini per il conteggio decimale flottante forzato o la precisione qualcosa del genere non riesce a ricordare quale sia il suo nome. – Dave

+1

Quale versione di PHP stai usando? 'php -v' o' phpinfo(); ' –

risposta

8

In circostanze normali il codice dovrebbe restituire il valore fluttuante 0.923076 ...

Il motivo si ottiene un numero intero arrotondato potrebbe essere perché avete il vostro set ini setting per "precision"-0, per risolvere questo o modificare il php.ini o utilizzare ini_set("precision", 3); nel codice prima del calcolo.

Un altro modo per risolvere questo è quello di utilizzare BCmath:

echo $value=bcdiv($a, $b, 3); 

E ancora un altro modo senza l'utilizzo di qualsiasi estensione è quello di utilizzare un piccolo trucco di matematica moltiplicando il valore che si desidera dividere per 1000 a ottenere 3 decimals.
In questo modo dividerete 12000 per 13 e l'intera parte sarà 923, quindi poiché moltiplicate per 1e3 inserite una virgola/punto prima dell'ultimo 3 più posti.

function divideFloat($a, $b, $precision=3) { 
    $a*=pow(10, $precision); 
    $result=(int)($a/$b); 
    if (strlen($result)==$precision) return '0.' . $result; 
    else return preg_replace('/(\d{' . $precision . '})$/', '.\1', $result); 
} 

echo divideFloat($a, $b); // 0.923

+1

No. Con precisione 0 abbiamo '0.9'.http: //www.php.net/manual/en/ini.core.php#ini.precision non è abbastanza chiaro; spiegazione più lunga: PHP usa la propria implementazione di ((v) s) analisi della stringa di stampa. La modalità '% H' è usata nella stringa di formato: chiama con il parametro' mode' impostato su '2' la funzione' zend_dtoa' in cui viene indicata la documentazione: '[modo] 2 ==> max (1, ndigits) cifre significative. Questo dà un valore di ritorno simile a quello di ecvt, tranne che gli zero finali sono soppressi. (Vedi: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_strtod.c#1457)) Ecco perché 'precision = 1' == 'precisione = 0'. – bwoebi

-1

Basta utilizzare $ value = (float) ($ x/y $); // Il risultato sarà in virgola mobile.

Cheers!

+5

- L'OP ha menzionato il tentativo di tipizzazione. –

9
echo $value = $x/(float) $y; 

Se lanci la variabile $y come galleggiare l'interprete usa la divisione in virgola mobile invece di divisione intera.

perché è l'impostazione predefinita per utilizzare la divisione integer su due variabili integer.

era diverso se è stato utilizzato $y = 13.0 (una variabile float al denominatore): Il risultato è sempre un numero float

+1

Spiega come la tua risposta risolve il problema in modo che i futuri visitatori possano trarre vantaggio da questa domanda. – War10ck

2

Tutte le altre risposte non sono giuste, perché la divisione di PHP restituirà sempre valori float, come affermato chiaramente nel manuale ufficiale PHP: Arithmetic Operators, ad eccezione dei casi in cui due operandi sono entrambi interi che possono essere equamente divisi.

In effetti, la domanda è sbagliata: il codice dovrebbe produrre 0,923 ..., come previsto dall'interrogante.

Sarcasticamente, la risposta ridotta (proveniente da @ BulletProof47) è l'unica altra che NON è SBAGLIATA (ma anche priva di significato).Chissà cosa stava pensando, ma scommetto tutti sanno perché è stato bocciato: D

Nel caso in cui chi è interessato, la funzione sottostante che fa la divisione in php è div_function, situato in Zend/zend_operators.c, riportata di seguito:

ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ 
{ 
    zval op1_copy, op2_copy; 
    int converted = 0; 

    while (1) { 
     switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) { 
      case TYPE_PAIR(IS_LONG, IS_LONG): 
       if (Z_LVAL_P(op2) == 0) { 
        zend_error(E_WARNING, "Division by zero"); 
        ZVAL_BOOL(result, 0); 
        return FAILURE;   /* division by zero */ 
       } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) { 
        /* Prevent overflow error/crash */ 
        ZVAL_DOUBLE(result, (double) LONG_MIN/-1); 
        return SUCCESS; 
       } 
       if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */ 
        ZVAL_LONG(result, Z_LVAL_P(op1)/Z_LVAL_P(op2)); 
       } else { 
        ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1))/Z_LVAL_P(op2)); 
       } 
       return SUCCESS; 
    ... 
Problemi correlati