Comment obtenir une partie entière et décimale d'un nombre?

98

Étant donné, disons, 1,25 - comment puis-je obtenir les parties "1" et "25" de ce nombre?

Je dois vérifier si la partie décimale est .0, .25, .5 ou .75.

StackOverflowNewbie
la source
Une simple explosion fonctionnera-t-elle? $ splitDec = exploser (".", $ décimal); $ splitDec [0] sera désormais de 1 et splitDec [1] sera désormais de 25 dans votre exemple.
Matt
@Matt split()est obsolète.
alex
@alex oui, j'ai oublié. Je pensais javascript. changé pour exploser.
Matt
@Matt, split est obsolète depuis PHP 5.3 et prend en fait une regex comme argument, alors qu'explode prend une chaîne. explode () est préféré dans ce cas.
Shelhamer
4
Sachez que explode(".",1.10);wil donnera 1 et 1, pas 1 et 10
Michel

Réponses:

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

Puis comparez avec 1/4, 1/2, 3/4, etc.


En cas de nombres négatifs, utilisez ceci:

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

L' $returnUnsignedempêche de faire -1,25 po à -1 et -0,25

Brad Christie
la source
7
En tant que côté, intval()ou simple casting qui (int)pourrait être plus performant quefloor()
Jason McCreary
1
Comment le plancher tient-il compte des négatifs?
LanceH
@LanceH: Ce n'est pas le cas, mais vous pouvez le faire gérer assez facilement avec un indicateur négatif.
Brad Christie
4
Cette réponse est en fait inexacte sauf si vous ajoutez un round (). Cela semble stupide, je sais, mais cela a à voir avec l'arithmétique des nombres à virgule flottante de bas niveau. Voir ici: stackoverflow.com/questions/3726721/php-math-precision
Matt James
Essayez avec 510,9, renvoie 0,89. Mais je ne peux pas dire pourquoi.
T30
38

Ce code le divisera pour vous:

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

où $ entier est le nombre entier et $ decimal aura les chiffres après la virgule décimale.

Shelhamer
la source
9
Sachez que explode(".",1.10);wil donnera 1 et 1, pas 1 et 10
Michel
3
Cela interrompt et jette un avertissement sur l'index non défini, si le nombre est un entier ou ne contient pas de partie décimale.
Andreyco
1
Cela suppose que le nombre ne finira pas par être représenté en notation scientifique lorsqu'il sera converti en chaîne. Si c'est un nombre vraiment vraiment énorme ou vraiment très petit, ce ne sera pas le cas et cette méthode échouera.
GordonM
20

Juste pour être différent :)

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

CodePad .

Comme avantage supplémentaire, il ne sera divisé que lorsque les deux côtés se composent de chiffres.

Alex
la source
2
Celui-ci ne casse pas si le nombre ne contient pas de partie décimale. Génial!
Andreyco
Bien que cela génère deux entiers; plutôt qu'un int et un flottant.
foochow
1
Cela suppose que le nombre ne finira pas par être représenté en notation scientifique lorsqu'il sera converti en chaîne. Si c'est un nombre vraiment vraiment énorme ou vraiment très petit, ce ne sera pas le cas et cette méthode échouera.
GordonM
18

La méthode floor () ne fonctionne pas pour les nombres négatifs. Cela fonctionne à chaque fois:

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

... fonctionne également pour les négatifs (même code, numéro différent):

$num = -5.7;
$whole = (int) $num;  // -5
$frac  = $num - $whole;  // -.7
le mec
la source
8

un chemin court (utilisez floor et fmod)

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

puis comparez $ decimal à 0, .25, .5 ou .75

mpalencia
la source
J'accepte cette réponse! C'est proche de C # (a % 1)ET il gère bien les nombres négatifs.
Bitterblue
7

Transformez-le en un entier et soustrayez-le

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

Ou juste pour obtenir la décimale à des fins de comparaison

$decimal = $your_number - (int)$your_number
Dom
la source
5

Il y a aussi une fonction fmod, qui peut être utilisée: fmod ($ my_var, 1) retournera le même résultat, mais parfois avec une petite erreur ronde.

ip512
la source
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
Vasil Nikolov
la source
2

C'est la manière dont j'utilise:

$float = 4.3;    

$dec = ltrim(($float - floor($float)),"0."); // result .3
Serdar Değirmenci
la source
1

La méthode de Brad Christie est essentiellement correcte, mais elle peut être écrite de manière plus concise.

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

    return $fraction;
}

Ceci est équivalent à sa méthode mais plus court et, espérons-le, plus facile à comprendre.

GordonM
la source
1
$x = 1.24

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

echo $result; // .24
Stnfordly
la source
1

Si vous pouvez vous attendre à ce qu'il ait toujours 2 décimales, vous pouvez simplement utiliser une opération de chaîne:

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

Aucune idée de performance mais pour mon cas simple c'était bien mieux ...

Ben Barreth
la source
Remarque: si vous faites cela, vous devriez au moins utiliser round ($ decimal, 2); d'abord pour vous assurer que vous n'avez que deux chiffres décimaux. Mais vous ne pouvez pas l'utiliser si vous voulez avoir des calculs corrects ou gérer de l'argent.
Ulrik McArdle le
0

Pour éviter la décimale flottante supplémentaire (c'est-à-dire 50,85 - 50 donne 0,850000000852), dans mon cas, j'ai juste besoin de 2 décimales pour les centimes d'argent.

$n = 50.85;
$whole = intval($n);
$fraction = $n * 100 % 100;
fbaudet
la source
0

J'avais du mal à trouver un moyen de séparer le montant en dollars et le montant après la virgule. Je pense que je l'ai surtout compris et j'ai pensé à partager si l'un d'entre vous avait des problèmes

Donc en gros...

si le prix est 1234,44 ... le tout serait 1234 et la décimale serait 44 ou

si le prix est 1234,01 ... le tout serait 1234 et le nombre décimal serait 01 ou

si le prix est 1234,10 ... le tout serait 1234 et la décimale serait 10

et ainsi de suite

$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;
Julie
la source
-1

Pas vu un simple module ici ...

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

Dans ce cas, obtenir à la fois $wholeAs?et$decimal ne dépend pas de l'autre. (Vous pouvez simplement prendre 1 des 3 sorties indépendamment.) J'ai montré $wholeAsFloatet $wholeAsIntparce quefloor() renvoie un nombre de type flottant même si le nombre qu'il renvoie sera toujours entier. (Ceci est important si vous transmettez le résultat dans un paramètre de fonction d'indication de type.)

Je voulais que cela divise un nombre d'heures / minutes à virgule flottante, par exemple 96,25, en heures et minutes séparément pour un instance de DateInterval en 96 heures 15 minutes. J'ai fait ceci comme suit:

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

Je me fichais des secondes dans mon cas.

Adambean
la source
-3
val = -3.1234

fraction = abs(val - as.integer(val) ) 
Guido C
la source
2
Salut, ajoutez un peu d'explication avec le code car cela aide à comprendre votre code. Les réponses au code uniquement sont mal vues.
Bhargav Rao