Как получить целую и десятичную часть числа?


99

Учитывая, скажем, 1,25 - как мне получить части этого числа «1» и «25»?

Мне нужно проверить, является ли десятичная часть 0,0, 0,25, 0,5 или 0,75.


Будет ли работать простой взрыв? $ splitDec = explode (".", $ десятичный); $ splitDec [0] теперь будет на 1, а splitDec [1] теперь будет 25 из вашего примера.
Мэтт

@Matt split()устарел.
Alex

@alex да, забыл. Думал javascript. изменен на взрыв.
Мэтт

@Matt, split устарел с PHP 5.3 и фактически принимает регулярное выражение в качестве аргумента, тогда как explode принимает строку. Explode () предпочтительнее в этом случае.
Shelhamer 08

4
Имейте в explode(".",1.10);виду, что вы получите 1 и 1, а не 1 и 10
Мишель

Ответы:


178
$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 08

@LanceH: Нет, но вы можете легко заставить его справиться с этим с помощью отрицательного флага.
Брэд Кристи

4
Этот ответ на самом деле неточен, если вы не добавите round (). Я знаю, звучит глупо, но это связано с арифметикой чисел с плавающей запятой низкого уровня. См. Здесь: 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
Это прерывается и выдает предупреждение о неопределенном индексе, если число является целым или не содержит десятичной части.
Andreyco

1
Это предполагает, что число не будет в конечном итоге представлено в экспоненциальной нотации при преобразовании в строку. Если это действительно очень большое или действительно очень маленькое число, тогда этого не будет, и этот метод сломается.
GordonM

20

Просто чтобы отличаться :)

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

CodePad .

В качестве дополнительного преимущества он будет разделяться только в том случае, если обе стороны состоят из цифр.


2
Этот не прерывается, если число не содержит десятичной части. Большой!
Andreyco

Приятно, что это выводит два целых числа; а не int и float.
foochow

1
Это предполагает, что число не будет в конечном итоге представлено в экспоненциальной нотации при преобразовании в строку. Если это действительно очень большое или действительно очень маленькое число, тогда этого не будет, и этот метод сломается.
GordonM

19

Метод 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

затем сравните $ decimal с 0, 0,25, 0,5 или 0,75


Принимаю этот ответ! Он близок к C # (a % 1)И хорошо обрабатывает отрицательные числа.
Bitterblue,

7

Преобразуйте его как int и вычтите

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

Или просто получить десятичную дробь для сравнения

$decimal = $your_number - (int)$your_number

5

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


4

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

Если вы можете рассчитывать на то, что он всегда имеет 2 десятичных знака, вы можете просто использовать строковую операцию:

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

Без понятия о производительности, но для моего простого случая это было намного лучше ...


Примечание: если вы это сделаете, вы должны хотя бы использовать round ($ decimal, 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
Привет, добавьте немного пояснений вместе с кодом, так как это помогает понять ваш код. Ответы только на код не одобряются.
Бхаргав Рао
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.