Як отримати цілу і десяткову частину числа?


98

Враховуючи, скажімо, 1,25 - як я можу отримати частини "1" та "25" від цього числа?

Мені потрібно перевірити, чи є десяткова частина .0, .25, .5 або .75.


Чи спрацює простий вибух? $ splitDec = вибухнути (".", $ десятичний); $ splitDec [0] тепер дорівнює 1, а splitDec [1] тепер буде 25 з вашого прикладу.
Метт

@Matt split()застарілий.
alex

@ Алекс так, забув. Думав javascript. змінився, щоб вибухнути.
Метт

@Matt, спліт був устареним, як у PHP 5.3, і фактично приймає регулярний вираз як аргумент, тоді як вибух займає рядок. explode () є кращим у цьому випадку.
шельхамер

4
Майте на увазі, що explode(".",1.10);дадуть 1 і 1, а не 1 і 10
Мішель

Відповіді:


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

Потім порівняйте проти 1/4, 1/2, 3/4 тощо.


У випадках від’ємного числа використовуйте це:

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

$returnUnsignedЗупиняє його від робити -1.25 , щоб -1 & -0.25


7
З іншого боку, intval()або простий кастинг, який (int)може бути більш ефективним, ніжfloor()
Джейсон МакКері,

1
Як підлога враховує негативи?
LanceH

@LanceH: Це не так, але ви можете змусити його легко впоратися з негативним прапором.
Бред Крісті

4
Ця відповідь насправді неточна, якщо ви не додасте круглий (). Я знаю, що це глухо, я знаю, але це пов'язано з арифметикою числа з плаваючою точкою низького рівня. Дивіться тут: stackoverflow.com/questions/3726721/php-math-precision
Метт Джеймс

Спробуйте з 510,9, повертає 0,89. Але не можу сказати, чому.
T30

38

Цей код розділить його на вас:

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

де $ whole - це ціле число, а $ decimal буде після цифр після коми.


9
Майте на увазі, що explode(".",1.10);дадуть 1 і 1, а не 1 і 10
Мішель

3
Це розриває і кидає попередження про невизначений індекс, якщо число є цілим чи не містить десяткової частини.
Андрейко

1
Це передбачає, що число не буде в кінцевому підсумку представлене в науковій нотації при передачі на рядок. Якщо це дійсно дуже величезне чи справді крихітне число, то це не буде так, і цей метод порушиться.
GordonM

20

Просто щоб бути іншим :)

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

CodePad .

В якості додаткової переваги він розділиться лише там, де обидві сторони складаються з цифр.


2
Цей не порушується, якщо число не містить десяткової частини. Чудово!
Андрейко

Приємно, що це виводить два цілих числа; а не int і float.
foochow

1
Це передбачає, що число не буде в кінцевому підсумку представлене в науковій нотації при передачі на рядок. Якщо це дійсно дуже величезне чи справді крихітне число, то це не буде так, і цей метод порушиться.
GordonM

18

Метод floor () не працює для від'ємних чисел. Це працює щоразу:

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

... також працює для негативів (той самий код, інша кількість):

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

8

короткий шлях (використовувати підлогу та fmod)

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

потім порівняйте $ десятковий з 0, .25, .5 або .75


Я приймаю цю відповідь! Це близько до C # 's (a % 1)І добре обробляє негативні числа.
Bitterblue

7

Відкиньте це як ціле і віднімання

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

Або просто для отримання десяткової для порівняння

$decimal = $your_number - (int)$your_number

5

Існує також функція fmod, яка може бути використана: fmod ($ my_var, 1) поверне той же результат, але колись з невеликою помилкою круглих.


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


1

Метод Бреда Крісті по суті правильний, але його можна написати більш стисло.

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

    return $fraction;
}

Це еквівалентно його методу, але коротший і, сподіваємось, простіше зрозуміти як результат.



1

Якщо ви можете розраховувати, що він завжди матиме два десяткових знаки, ви можете просто скористатися рядковою операцією:

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

Поняття про продуктивність не маю, але для мого простого випадку це було набагато краще ...


Примітка: якщо ви це зробите, вам слід принаймні використовувати круглий ($ десятковий, 2); спочатку переконайтеся, що у вас є лише дві цифри у вигляді десяткової. Але ви не можете цим скористатися, якщо хочете мати правильну математику чи обробляти гроші.
Ульрік Макардл

0

Щоб запобігти додатковій десятковій плавці (тобто 50,85 - 50 дають 0,850000000852), у моєму випадку мені просто потрібно 2 десяткові дроби за грошові центи.

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

0

Мені важко було знайти спосіб фактично розділити суму долара та суму після десяткової. Я думаю, що я зрозумів це здебільшого і подумав поділитися, якщо у когось із жовних виникли проблеми

Так в основному ...

якщо ціна - 1234,44 ... ціла буде 1234, а десяткова - 44 або

якщо ціна становить 1234,01 ... ціла буде 1234, а десяткова - 01 або

якщо ціна - 1234,10 ... ціла буде 1234, а десяткова - 10

і так далі

$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

Тут не бачили простого модуля ...

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

У цьому випадку отримувати і те, $wholeAs?і інше $decimalне залежить від іншого. (Ви можете просто взяти 1 з 3 виходів незалежно.) Я показав $wholeAsFloatі $wholeAsIntтому, що floor()повертає число з поплавковим типом, хоча число, яке воно повертає, завжди буде цілим. (Це важливо, якщо ви передаєте результат у параметр функції з натяком на тип.)

Я хотів, щоб це розділило число годин / хвилин з плаваючою комою, наприклад 96,25, на години і хвилини окремо для екземпляра DateInterval, як 96 годин 15 хвилин. Я зробив це так:

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

Мені не було байдуже секунд у моєму випадку.


-3
val = -3.1234

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

2
Привіт, додайте трохи пояснень разом із кодом, оскільки це допоможе зрозуміти ваш код. Відповіді лише на коди знущаються.
Bhargav Rao
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.