Bagaimana cara mendapatkan bagian bilangan bulat dan desimal?


98

Diberikan, katakanlah, 1,25 - bagaimana cara mendapatkan bagian "1" dan. "25" dari nomor ini?

Saya perlu memeriksa apakah bagian desimalnya adalah .0, .25, .5, atau .75.


Akankah ledakan sederhana berhasil? $ splitDec = meledak (".", $ desimal); $ splitDec [0] sekarang akan menjadi 1 dan splitDec [1] sekarang akan menjadi 25 dari contoh Anda.
Matt

@Matt split()sudah ditinggalkan.
alex

@alex ya, lupa. Sedang memikirkan javascript. berubah menjadi meledak.
Matt

@Matt, split sudah tidak digunakan lagi sejak PHP 5.3 dan sebenarnya menggunakan regex sebagai arg-nya, sedangkan explode membutuhkan string. explode () lebih disukai dalam kasus ini.
shelhamer

4
Ketahuilah bahwa explode(".",1.10);wil memberikan 1 dan 1, bukan 1 dan 10
Michel

Jawaban:


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

Kemudian bandingkan dengan 1/4, 1/2, 3/4, dll.


Dalam kasus angka negatif, gunakan ini:

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

The $returnUnsignedberhenti dari membuat -1,25 ke -1 & -0,25


7
Sebagai sampingan, intval()atau casting sederhana (int)mungkin lebih berkinerja daripadafloor()
Jason McCreary

1
Bagaimana floor menghitung negatif?
LanceH

@LanceH: Memang tidak, tetapi Anda dapat membuatnya menanganinya dengan mudah dengan tanda negatif.
Brad Christie

4
Jawaban ini sebenarnya tidak akurat kecuali Anda menambahkan putaran (). Kedengarannya bodoh, saya tahu, tapi ini ada hubungannya dengan aritmatika angka floating point tingkat rendah. Lihat di sini: stackoverflow.com/questions/3726721/php-math-precision
Matt James

Coba dengan 510.9, menghasilkan 0.89. Tapi tidak tahu kenapa.
T30

38

Kode ini akan membaginya untuk Anda:

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

dengan $ whole adalah bilangan bulat dan $ decimal akan memiliki digit setelah koma desimal.


9
Ketahuilah bahwa explode(".",1.10);wil memberikan 1 dan 1, bukan 1 dan 10
Michel

3
Ini memecah dan melempar peringatan tentang indeks yang tidak ditentukan, jika angka adalah integer atau tidak berisi bagian desimal.
Andreyco

1
Ini mengasumsikan bahwa nomor tersebut tidak akan berakhir diwakili dalam notasi ilmiah ketika dilemparkan ke string. Jika jumlahnya sangat besar atau sangat kecil maka ini tidak akan menjadi masalah dan metode ini akan rusak.
GordonM

20

Hanya untuk menjadi berbeda :)

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

CodePad .

Sebagai keuntungan tambahan, ini hanya akan dibagi dimana kedua sisinya terdiri dari angka.


2
Yang ini tidak rusak jika angka tidak mengandung bagian desimal. Bagus!
Andreyco

Bagus karena ini menghasilkan dua bilangan bulat; daripada int dan float.
foochow

1
Ini mengasumsikan bahwa nomor tersebut tidak akan berakhir diwakili dalam notasi ilmiah ketika dilemparkan ke string. Jika jumlahnya sangat besar atau sangat kecil maka ini tidak akan menjadi masalah dan metode ini akan rusak.
GordonM

18

Metode floor () tidak berfungsi untuk bilangan negatif. Ini berfungsi setiap saat:

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

... juga berfungsi untuk negatif (kode sama, nomor berbeda):

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

8

cara singkat (gunakan floor dan fmod)

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

lalu bandingkan $ desimal dengan 0, .25, .5, atau .75


Saya menerima jawaban ini! Ini dekat dengan C # (a % 1)DAN menangani angka negatif dengan baik.
Bitterblue

7

Tuang sebagai int dan kurangi

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

Atau hanya untuk mendapatkan desimal untuk perbandingan

$decimal = $your_number - (int)$your_number

5

Ada juga fungsi fmod, yang dapat digunakan: fmod ($ my_var, 1) akan mengembalikan hasil yang sama, tetapi terkadang dengan kesalahan putaran kecil.


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

Ini cara yang saya gunakan:

$float = 4.3;    

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

1

Metode Brad Christie pada dasarnya benar tetapi dapat ditulis lebih ringkas.

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

    return $fraction;
}

Ini sama dengan metodenya tetapi lebih singkat dan semoga hasilnya lebih mudah dipahami.



1

Jika Anda dapat mengandalkannya selalu memiliki 2 tempat desimal, Anda dapat menggunakan operasi string:

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

Tidak tahu kinerja tetapi untuk kasus sederhana saya ini jauh lebih baik ...


Catatan: jika Anda melakukan ini, Anda setidaknya harus menggunakan round ($ decimal, 2); pertama untuk memastikan Anda hanya memiliki dua digit sebagai desimal. Tetapi Anda tidak dapat menggunakan ini jika Anda ingin memiliki matematika yang benar atau menangani uang.
Ulrik McArdle

0

Untuk mencegah desimal float ekstra (yaitu 50.85 - 50 memberikan 0.850000000852), dalam kasus saya, saya hanya perlu 2 desimal untuk sen uang.

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

0

Saya mengalami kesulitan menemukan cara untuk benar-benar memisahkan jumlah dolar dan jumlah setelah desimal. Saya pikir saya kebanyakan mengetahuinya dan berpikir untuk berbagi jika ada di antara kalian yang mengalami masalah

Jadi pada dasarnya...

jika harga adalah 1234.44 ... keseluruhan akan menjadi 1234 dan desimal menjadi 44 atau

jika harga 1234.01 ... keseluruhan akan menjadi 1234 dan desimal akan menjadi 01 atau

jika harga 1234.10 ... keseluruhan menjadi 1234 dan desimal menjadi 10

Dan seterusnya

$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

Tidak terlihat modulus sederhana di sini ...

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

Dalam hal ini mendapatkan keduanya $wholeAs?dan $decimaltidak bergantung pada yang lain. (Anda bisa mengambil 1 dari 3 keluaran secara independen.) Saya telah menunjukkan $wholeAsFloatdan $wholeAsIntkarenafloor() mengembalikan nomor tipe float meskipun nomor yang dikembalikan akan selalu utuh. (Ini penting jika Anda meneruskan hasilnya ke parameter fungsi petunjuk tipe.)

Saya ingin ini membagi jumlah floating point dari jam / menit, misalnya 96.25, menjadi jam dan menit secara terpisah untuk instance DateInterval sebagai 96 jam 15 menit. Saya melakukan ini sebagai berikut:

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

Saya tidak peduli tentang detik dalam kasus saya.


-3
val = -3.1234

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

2
Hai, tambahkan sedikit penjelasan bersama dengan kode karena membantu memahami kode Anda. Kode hanya jawaban tidak disukai.
Bhargav Rao
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.