Come ottenere la parte intera e decimale di un numero?


98

Dato, diciamo, 1,25, come faccio a ottenere parti "1" e "25" di questo numero?

Devo controllare se la parte decimale è .0, .25, .5 o .75.


Funzionerà una semplice esplosione? $ splitDec = explode (".", $ decimal); $ splitDec [0] ora sarà 1 e splitDec [1] ora sarà 25 dal tuo esempio.
Matt

@Matt split()è stato deprecato.
alex

@alex yea, dimenticato. Stavo pensando a javascript. cambiato per esplodere.
Matt

@ Matt, split è stato deprecato a partire da PHP 5.3 e in realtà prende una regex come argomento, mentre explode accetta una stringa. explode () è preferibile in questo caso.
Shelhamer

4
Tieni presente che explode(".",1.10);darà 1 e 1, non 1 e 10
Michel

Risposte:


178
$n = 1.25;
$whole = floor($n);      // 1
$fraction = $n - $whole; // .25

Quindi confronta con 1/4, 1/2, 3/4, ecc.


In caso di numeri negativi, usa questo:

function NumberBreakdown($number, $returnUnsigned = false)
{
  $negative = 1;
  if ($number < 0)
  {
    $negative = -1;
    $number *= -1;
  }

  if ($returnUnsigned){
    return array(
      floor($number),
      ($number - floor($number))
    );
  }

  return array(
    floor($number) * $negative,
    ($number - floor($number)) * $negative
  );
}

Gli $returnUnsignedimpedisce di fare -1,25 pollici a -1 e -0,25


7
Come lato, intval()o semplice casting come (int)potrebbe essere più performante difloor()
Jason McCreary

1
In che modo floor tiene conto dei negativi?
LanceH

@ LanceH: Non è così, ma puoi farlo gestire abbastanza facilmente con un flag negativo.
Brad Christie

4
Questa risposta è in realtà imprecisa a meno che non si aggiunga un round (). Sembra stupido, lo so, ma ha a che fare con l'aritmetica dei numeri in virgola mobile di basso livello. Vedi qui: stackoverflow.com/questions/3726721/php-math-precision
Matt James,

Prova con 510,9, restituisce 0,89. Ma non so dire perché.
T30

38

Questo codice lo dividerà per te:

list($whole, $decimal) = explode('.', $your_number);

dove $ intero è il numero intero e $ decimale avrà le cifre dopo il punto decimale.


9
Tieni presente che explode(".",1.10);darà 1 e 1, non 1 e 10
Michel

3
Questo interrompe e genera un avviso sull'indice non definito, se il numero è intero o non contiene una parte decimale.
Andreyco

1
Ciò presuppone che il numero non finirà per essere rappresentato in notazione scientifica quando cast su stringa. Se è un numero davvero davvero enorme o davvero molto piccolo, non sarà così e questo metodo non funzionerà.
GordonM

20

Solo per essere diversi :)

list($whole, $decimal) = sscanf(1.5, '%d.%d');

CodePad .

Come ulteriore vantaggio, si dividerà solo dove entrambi i lati sono costituiti da cifre.


2
Questo non si rompe se il numero non contiene la parte decimale. Grande!
Andreyco

Bello che questo restituisca due numeri interi; piuttosto che un int e un float.
foochow

1
Ciò presuppone che il numero non finirà per essere rappresentato in notazione scientifica quando cast su stringa. Se è un numero davvero davvero enorme o davvero molto piccolo, non sarà così e questo metodo non funzionerà.
GordonM

18

Il metodo floor () non funziona per i numeri negativi. Funziona ogni volta:

$num = 5.7;
$whole = (int) $num;  // 5
$frac  = $num - $whole;  // .7

... funziona anche per i negativi (stesso codice, numero diverso):

$num = -5.7;
$whole = (int) $num;  // -5
$frac  = $num - $whole;  // -.7

8

un percorso breve (usa floor e fmod)

$var = "1.25";
$whole = floor($var);     // 1
$decimal = fmod($var, 1); //0.25

quindi confronta $ decimal con 0, .25, .5 o .75


Accetto questa risposta! È vicino all'AND di C # (a % 1)gestisce bene i numeri negativi.
Bitterblue

7

Lancialo come int e sottrarre

$integer = (int)$your_number;
$decimal = $your_number - $integer;

O solo per ottenere il decimale per il confronto

$decimal = $your_number - (int)$your_number

5

C'è anche una funzione fmod, che può essere usata: fmod ($ my_var, 1) restituirà lo stesso risultato, ma a volte con un piccolo errore di round.


3

PHP 5.4+

$n = 12.343;
intval($n); // 12
explode('.', number_format($n, 1))[1]; // 3
explode('.', number_format($n, 2))[1]; // 34
explode('.', number_format($n, 3))[1]; // 343
explode('.', number_format($n, 4))[1]; // 3430

2

Questo è il modo in cui uso:

$float = 4.3;    

$dec = ltrim(($float - floor($float)),"0."); // result .3

1

Il metodo di Brad Christie è essenzialmente corretto ma può essere scritto in modo più conciso.

function extractFraction ($value) 
{
    $fraction   = $value - floor ($value);
    if ($value < 0)
    {
        $fraction *= -1;
    }

    return $fraction;
}

Questo è equivalente al suo metodo, ma di conseguenza più breve e, si spera, più facile da capire.


1
$x = 1.24

$result = $x - floor($x);

echo $result; // .24

1

Se puoi contare su di esso avendo sempre 2 cifre decimali, puoi semplicemente usare un'operazione su stringa:

$decimal = 1.25;
substr($decimal,-2);  // returns "25" as a string

Nessuna idea di prestazioni ma per il mio semplice caso era molto meglio ...


Nota: se lo fai, dovresti almeno usare round ($ decimal, 2); prima per assicurarti di avere solo due cifre come decimali. Ma non puoi usarlo se vuoi avere una matematica corretta o gestire i soldi.
Ulrik McArdle,

0

Per evitare il float decimale extra (cioè 50.85 - 50 dare 0.850000000852), nel mio caso ho solo bisogno di 2 decimali per i centesimi di denaro.

$n = 50.85;
$whole = intval($n);
$fraction = $n * 100 % 100;

0

Stavo avendo difficoltà a trovare un modo per separare effettivamente l'importo in dollari e l'importo dopo il decimale. Penso di averlo capito per lo più e ho pensato di condividere se qualcuno di voi avesse avuto problemi

Quindi in poche parole...

se il prezzo è 1234,44 ... intero sarebbe 1234 e il decimale sarebbe 44 o

se il prezzo è 1234,01 ... intero sarebbe 1234 e il decimale sarebbe 01 o

se il prezzo è 1234,10 ... intero sarebbe 1234 e il decimale sarebbe 10

e così via

$price = 1234.44;

$whole = intval($price); // 1234
$decimal1 = $price - $whole; // 0.44000000000005 uh oh! that's why it needs... (see next line)
$decimal2 = round($decimal1, 2); // 0.44 this will round off the excess numbers
$decimal = substr($decimal2, 2); // 44 this removed the first 2 characters

if ($decimal == 1) { $decimal = 10; } // Michel's warning is correct...
if ($decimal == 2) { $decimal = 20; } // if the price is 1234.10... the decimal will be 1...
if ($decimal == 3) { $decimal = 30; } // so make sure to add these rules too
if ($decimal == 4) { $decimal = 40; }
if ($decimal == 5) { $decimal = 50; }
if ($decimal == 6) { $decimal = 60; }
if ($decimal == 7) { $decimal = 70; }
if ($decimal == 8) { $decimal = 80; }
if ($decimal == 9) { $decimal = 90; }

echo 'The dollar amount is ' . $whole . ' and the decimal amount is ' . $decimal;

-1

Non visto un semplice modulo qui ...

$number         = 1.25;
$wholeAsFloat   = floor($number);   // 1.00
$wholeAsInt     = intval($number);  // 1
$decimal        = $number % 1;      // 0.25

In questo caso prendi entrambi $wholeAs?e $decimalnon dipendere dall'altro. (Puoi semplicemente prendere 1 delle 3 uscite in modo indipendente.) Ho mostrato $wholeAsFloate $wholeAsIntperchéfloor() restituisce un numero di tipo float anche se il numero restituito sarà sempre intero. (Questo è importante se stai passando il risultato in un parametro di funzione con suggerimento sul tipo.)

Volevo che questo dividesse un numero in virgola mobile di ore / minuti, ad esempio 96.25, in ore e minuti separatamente per un'istanza di DateInterval come 96 ore e 15 minuti. L'ho fatto come segue:

$interval = new \DateInterval(sprintf("PT%dH%dM", intval($hours), (($hours % 1) * 60)));

Non mi interessavano i secondi nel mio caso.


-3
val = -3.1234

fraction = abs(val - as.integer(val) ) 

2
Ciao, aggiungi un po 'di spiegazione insieme al codice in quanto aiuta a capire il tuo codice. Solo le risposte in codice sono disapprovate.
Bhargav Rao
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.