Jak uzyskać część całkowitą i dziesiętną liczby?

98

Biorąc pod uwagę, powiedzmy, 1,25 - jak uzyskać części „1” i „25” tej liczby?

Muszę sprawdzić, czy część dziesiętna to .0, .25, .5 lub .75.

StackOverflowNewbie
źródło
Czy zwykły wybuch zadziała? $ splitDec = eksplodować (".", $ dziesiętny); $ splitDec [0] będzie teraz równe 1, a splitDec [1] będzie miało teraz wartość 25 z twojego przykładu.
Matt,
@Matt split()został wycofany.
Alex
@alex yea, zapomniałem. Myślałem o javascript. zmieniony na wybuch.
Matt,
@Matt, split został uznany za przestarzały w PHP 5.3 i faktycznie przyjmuje wyrażenie regularne jako argument, podczas gdy explode przyjmuje ciąg. W tym przypadku preferowana jest opcja explode ().
shelhamer
4
Pamiętaj, że explode(".",1.10);poda 1 i 1, a nie 1 i 10
Michel

Odpowiedzi:

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

Następnie porównaj z 1/4, 1/2, 3/4 itd.


W przypadku liczb ujemnych użyj tego:

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

$returnUnsignedZatrzymuje się go z co -1.25 do -1 i -0,25

Brad Christie
źródło
7
Na boku intval()lub po prostu casting, który (int)może być bardziej spektakularny niżfloor()
Jason McCreary
1
Jak podłoga odpowiada za negatywy?
LanceH,
@LanceH: Tak nie jest, ale możesz sobie z tym poradzić, używając flagi negatywnej.
Brad Christie,
4
Ta odpowiedź jest w rzeczywistości niedokładna, chyba że dodasz round (). Wiem, brzmi głupio, ale ma to związek z arytmetyką liczb zmiennoprzecinkowych na niskim poziomie. Zobacz tutaj: stackoverflow.com/questions/3726721/php-math-precision
Matt James
Spróbuj z 510,9, zwraca 0,89. Ale nie mogę powiedzieć, dlaczego.
T30
38

Ten kod podzieli go za Ciebie:

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

gdzie $ całość to liczba całkowita, a $ dziesiętne będą miały cyfry po przecinku.

Shelhamer
źródło
9
Pamiętaj, że explode(".",1.10);poda 1 i 1, a nie 1 i 10
Michel
3
To przerywa i wyświetla ostrzeżenie o niezdefiniowanym indeksie, jeśli liczba jest liczbą całkowitą lub nie zawiera części dziesiętnej.
Andreyco
1
Zakłada się, że liczba nie zostanie ostatecznie przedstawiona w notacji naukowej, gdy zostanie rzucona na łańcuch. Jeśli jest to naprawdę bardzo duża lub naprawdę bardzo mała liczba, to tak nie jest i ta metoda się zepsuje.
GordonM
20

Po prostu być innym :)

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

CodePad .

Dodatkową korzyścią jest podział tylko wtedy, gdy obie strony składają się z cyfr.

Alex
źródło
2
Ten nie pęka, jeśli liczba nie zawiera części dziesiętnej. Wspaniały!
Andreyco
Fajnie, że daje to dwie liczby całkowite; zamiast int i float.
foochow
1
Zakłada się, że liczba nie zostanie ostatecznie przedstawiona w notacji naukowej, gdy zostanie rzucona na łańcuch. Jeśli jest to naprawdę bardzo duża lub naprawdę bardzo mała liczba, to tak nie jest i ta metoda się zepsuje.
GordonM
18

Metoda floor () nie działa w przypadku liczb ujemnych. Działa to za każdym razem:

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

... działa również w przypadku negatywów (ten sam kod, inna liczba):

$num = -5.7;
$whole = (int) $num;  // -5
$frac  = $num - $whole;  // -.7
koleś
źródło
8

krótka droga (użyj floor i fmod)

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

następnie porównaj $ dziesiętnie z 0, 0,25, .5 lub 0,75

mpalencia
źródło
Przyjmuję tę odpowiedź! Jest blisko C # (a % 1)i dobrze obsługuje liczby ujemne.
Bitterblue
7

Rzuć to jako int i odejmij

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

Lub po prostu uzyskać ułamek dziesiętny do porównania

$decimal = $your_number - (int)$your_number
Dom
źródło
5

Istnieje również funkcja fmod, której można użyć: fmod ($ my_var, 1) zwróci ten sam wynik, ale czasami z małym okrągłym błędem.

ip512
źródło
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
źródło
2

Oto sposób, w jaki używam:

$float = 4.3;    

$dec = ltrim(($float - floor($float)),"0."); // result .3
Serdar Değirmenci
źródło
1

Metoda Brada Christiego jest zasadniczo poprawna, ale można ją napisać bardziej zwięźle.

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

    return $fraction;
}

Jest to odpowiednik jego metody, ale w rezultacie krótszy i miejmy nadzieję, łatwiejszy do zrozumienia.

Gordon M.
źródło
1
$x = 1.24

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

echo $result; // .24
Stnfordly
źródło
1

Jeśli możesz liczyć na to, że zawsze ma 2 miejsca po przecinku, możesz po prostu użyć operacji na łańcuchach:

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

Nie mam pojęcia o wydajności, ale w moim prostym przypadku było znacznie lepiej ...

Ben Barreth
źródło
Uwaga: jeśli to zrobisz, powinieneś przynajmniej użyć round ($ decimal, 2); najpierw, aby upewnić się, że masz tylko dwie cyfry jako dziesiętne. Ale nie możesz tego użyć, jeśli chcesz mieć poprawną matematykę lub radzić sobie z pieniędzmi.
Ulrik McArdle
0

Aby zapobiec dodatkowym liczbom dziesiętnym typu float (tj. 50,85 - 50 daje 0,850000000852), w moim przypadku potrzebuję tylko 2 miejsc po przecinku dla centów pieniężnych.

$n = 50.85;
$whole = intval($n);
$fraction = $n * 100 % 100;
fbaudet
źródło
0

Trudno mi było znaleźć sposób na oddzielenie kwoty w dolarach od kwoty po przecinku. Myślę, że przeważnie to rozgryzłem i pomyślałem, że podzielę się, jeśli któryś z was miałby problemy

Więc w zasadzie ...

jeśli cena wynosi 1234,44 ... całość będzie równa 1234, a liczba dziesiętna to 44 lub

jeśli cena wynosi 1234,01 ... całość będzie wynosić 1234, a dziesiętnie to 01 lub

jeśli cena wynosi 1234,10 ... całość będzie równa 1234, a dziesiętna - 10

i tak dalej

$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
źródło
-1

Nie widziałem tutaj prostego modułu ...

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

W tym przypadku otrzymanie obu $wholeAs?i $decimalnie zależy od drugiego. (Możesz po prostu wziąć jedno z 3 wyjść niezależnie.) Pokazałem $wholeAsFloati $wholeAsIntponieważfloor() zwraca liczbę typu zmiennoprzecinkowego, mimo że liczba, którą zwraca, zawsze będzie pełna. (Jest to ważne, jeśli przekazujesz wynik do parametru funkcji ze wskazówkami do typu).

Chciałem podzielić zmiennoprzecinkową liczbę godzin / minut, np. 96,25, na godziny i minuty oddzielnie dla instancji DateInterval jako 96 godzin 15 minut. Zrobiłem to w następujący sposób:

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

W moim przypadku nie obchodziły mnie sekundy.

Adambean
źródło
-3
val = -3.1234

fraction = abs(val - as.integer(val) ) 
Guido C
źródło
2
Cześć, dodaj trochę wyjaśnienia wraz z kodem, ponieważ pomaga to zrozumieć twój kod. Odpowiedzi zawierające tylko kod są źle widziane.
Bhargav Rao