Wie bekomme ich einen ganzen und einen dezimalen Teil einer Zahl?

98

Wenn Sie beispielsweise 1,25 angeben, wie erhalte ich "1" und "25" Teile dieser Zahl?

Ich muss überprüfen, ob der Dezimalteil .0, .25, .5 oder .75 ist.

StackOverflowNewbie
quelle
Funktioniert eine einfache Explosion? $ splitDec = explode (".", $ decimal); $ splitDec [0] wird jetzt durch die 1 und splitDec [1] wird jetzt 25 von Ihrem Beispiel sein.
Matt
@Matt split()ist veraltet.
Alex
@alex ja, vergessen. Dachte Javascript. geändert, um zu explodieren.
Matt
@Matt, split ist ab PHP 5.3 veraltet und verwendet tatsächlich einen regulären Ausdruck als Argument, während explode eine Zeichenfolge verwendet. explode () wird in diesem Fall bevorzugt.
Shelhamer
4
Seien Sie sich bewusst, explode(".",1.10);dass Sie 1 und 1 geben werden, nicht 1 und 10
Michel

Antworten:

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

Dann vergleiche mit 1/4, 1/2, 3/4 usw.


Verwenden Sie bei negativen Zahlen Folgendes:

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

Das $returnUnsignedhält es davon ab, -1,25 in -1 & -0,25 zu machen

Brad Christie
quelle
7
Als Seite intval()oder einfaches Casting, das (int)vielleicht performanter ist alsfloor()
Jason McCreary
1
Wie berücksichtigt Floor Negative?
LanceH
@LanceH: Das tut es nicht, aber Sie können es mit einer negativen Flagge ziemlich einfach handhaben.
Brad Christie
4
Diese Antwort ist tatsächlich ungenau, es sei denn, Sie fügen eine Runde hinzu (). Klingt dumm, ich weiß, aber es hat mit Gleitkommazahlenarithmetik auf niedriger Ebene zu tun. Siehe hier: stackoverflow.com/questions/3726721/php-math-precision
Matt James
Versuchen Sie es mit 510,9, und geben Sie 0,89 zurück. Kann aber nicht sagen warum.
T30
38

Dieser Code teilt es für Sie auf:

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

Dabei ist $ ganz die ganze Zahl und $ dezimal die Ziffern nach dem Dezimalpunkt.

Shelhamer
quelle
9
Seien Sie sich bewusst, explode(".",1.10);dass Sie 1 und 1 geben werden, nicht 1 und 10
Michel
3
Dies unterbricht und warnt vor einem undefinierten Index, wenn die Zahl eine Ganzzahl ist oder keinen Dezimalteil enthält.
Andreyco
1
Dies setzt voraus, dass die Zahl nicht in wissenschaftlicher Notation dargestellt wird, wenn sie in einen String umgewandelt wird. Wenn es sich um eine wirklich sehr große oder sehr kleine Zahl handelt, ist dies nicht der Fall und diese Methode wird nicht funktionieren.
GordonM
20

Nur um anders zu sein :)

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

CodePad .

Als zusätzlichen Vorteil wird es nur aufgeteilt, wenn beide Seiten aus Ziffern bestehen.

Alex
quelle
2
Dieser wird nicht unterbrochen, wenn die Zahl keinen Dezimalteil enthält. Toll!
Andreyco
Schön, dass dies zwei ganze Zahlen ausgibt; eher als ein int und ein float.
Foochow
1
Dies setzt voraus, dass die Zahl nicht in wissenschaftlicher Notation dargestellt wird, wenn sie in einen String umgewandelt wird. Wenn es sich um eine wirklich sehr große oder sehr kleine Zahl handelt, ist dies nicht der Fall und diese Methode wird nicht funktionieren.
GordonM
18

Die floor () -Methode funktioniert nicht für negative Zahlen. Dies funktioniert jedes Mal:

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

... funktioniert auch für Negative (gleicher Code, unterschiedliche Nummer):

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

ein kurzer weg (benutze boden und fmod)

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

Vergleichen Sie dann $ decimal mit 0, .25, .5 oder .75

mpalencia
quelle
Ich akzeptiere diese Antwort! Es liegt in der Nähe von C # (a % 1)UND verarbeitet negative Zahlen gut.
Bitterblue
7

Wirf es als int und subtrahiere

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

Oder nur um die Dezimalstelle zum Vergleich zu erhalten

$decimal = $your_number - (int)$your_number
Dom
quelle
5

Es gibt auch eine fmod-Funktion, die verwendet werden kann: fmod ($ my_var, 1) gibt das gleiche Ergebnis zurück, jedoch manchmal mit einem kleinen runden Fehler.

ip512
quelle
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
quelle
2

Dies ist der Weg, den ich benutze:

$float = 4.3;    

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

Brad Christies Methode ist im Wesentlichen korrekt, kann aber präziser geschrieben werden.

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

    return $fraction;
}

Dies entspricht seiner Methode, ist jedoch kürzer und dadurch hoffentlich leichter zu verstehen.

GordonM
quelle
1
$x = 1.24

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

echo $result; // .24
Stnfordly
quelle
1

Wenn Sie sich darauf verlassen können, dass es immer 2 Dezimalstellen hat, können Sie einfach eine Zeichenfolgenoperation verwenden:

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

Keine Ahnung von Leistung, aber für meinen einfachen Fall war das viel besser ...

Ben Barreth
quelle
Hinweis: Wenn Sie dies tun, sollten Sie mindestens round ($ decimal, 2) verwenden. Stellen Sie zunächst sicher, dass Sie nur zwei Dezimalstellen haben. Sie können dies jedoch nicht verwenden, wenn Sie die richtige Mathematik haben oder mit Geld umgehen möchten.
Ulrik McArdle
0

Um die zusätzliche Gleitkommazahl zu vermeiden (dh 50,85 - 50 ergeben 0,850000000852), benötige ich in meinem Fall nur 2 Dezimalstellen für Geld-Cent.

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

Es fiel mir schwer, einen Weg zu finden, um den Dollarbetrag und den Betrag nach der Dezimalstelle tatsächlich zu trennen. Ich glaube, ich habe es meistens herausgefunden und dachte, ich sollte mitteilen, ob jemand von euch Probleme hat

Also im Grunde genommen...

Wenn der Preis 1234,44 ist ... wäre das Ganze 1234 und die Dezimalstelle wäre 44 oder

Wenn der Preis 1234,01 ist ... wäre das Ganze 1234 und die Dezimalstelle wäre 01 oder

Wenn der Preis 1234,10 ist, wäre das Ganze 1234 und die Dezimalstelle 10

und so weiter

$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
quelle
-1

Ich habe hier keinen einfachen Modul gesehen ...

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

In diesem Fall beides bekommen $wholeAs?und $decimalnicht vom anderen abhängen. (Sie können nur 1 der 3 Ausgänge unabhängig voneinander nehmen.) Ich habe gezeigt $wholeAsFloatund $wholeAsIntweilfloor() eine Float-Typ-Nummer zurückgegeben wird, obwohl die zurückgegebene Nummer immer ganz ist. (Dies ist wichtig, wenn Sie das Ergebnis an einen typabhängigen Funktionsparameter übergeben.)

Ich wollte, dass eine Gleitkommazahl von Stunden / Minuten, z. B. 96,25, für eine DateInterval- Instanz getrennt in Stunden und Minuten als 96 Stunden 15 Minuten aufgeteilt wird. Ich habe das wie folgt gemacht:

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

Sekunden waren mir in meinem Fall egal.

Adambean
quelle
-3
val = -3.1234

fraction = abs(val - as.integer(val) ) 
Guido C.
quelle
2
Hallo, fügen Sie zusammen mit dem Code eine Erklärung hinzu, da dies zum Verständnis Ihres Codes beiträgt. Nur Code-Antworten sind verpönt.
Bhargav Rao