PHP проверяет, является ли переменная целым числом

У меня есть этот код PHP:

$entityElementCount = (-($highScore-$totalKeywordCount))/0.29; 

Я хочу знать, как проверить, является ли $ entityElementCount целым числом (2, 6, …) или частичным (2.33, 6.2, …).

Спасибо!

 $entityElementCount = (-($highScore-$totalKeywordCount))/0.29; if (ctype_digit($entityElementCount) ){ // (ctype_digit((string)$entityElementCount)) // as advised. print "whole number\n"; }else{ print "not whole number\n"; } 
 if(floor($number) == $number) 

Я знаю, что это старо, но я думал, что поделюсь тем, что я только что нашел:

Использовать fmod и проверить на 0

 $entityElementCount = (-($highScore-$totalKeywordCount))/0.29; if (fmod($entityElementCount,1) != 0) { echo 'Not a whole number!'; } else { echo 'A whole number!'; } 

fmod отличается от%, потому что, если у вас есть доля,%, похоже, не работает для меня (он возвращает 0 … например, echo 9.4 % 1; будет выводить 0 ). С помощью fmod вы получите долю дроби. Например:

echo fmod(9.4, 1);

Выйдет 0.4

Основной способ, как сказал Чача, – это

 if (floor($number) == $number) 

Однако типы с плавающей точкой не могут точно хранить числа, а это означает, что 1 может быть сохранен как 0.999999997. Конечно, это означает, что вышеуказанная проверка завершится неудачно, потому что она будет округлена до 0, хотя для ваших целей она достаточно близка к 1, чтобы считаться целым числом. Поэтому попробуйте что-то вроде этого:

 if (abs($number - round($number)) < 0.0001) 

Если вы знаете, что он будет числовым (это означает, что он никогда не будет целым числом, отличным от строки, например "ten" или "100" , вы можете просто использовать is_int() :

 $entityElementCount = (-($highScore-$totalKeywordCount))/0.29; $entityWholeNumber = is_int($entityElementCount); echo ($entityWholeNumber) ? "Whole Number!" : "Not a whole number!"; 

Я бы использовал функцию intval :

 if($number === intval($number)) { } 

тесты:

 var_dump(10 === intval(10)); // prints "bool(true)" var_dump("10" === intval("10")); // prints "bool(false)" var_dump(10.5 === intval(10.5)); // prints "bool(false)" var_dump("0x539" === intval("0x539")); // prints "bool(false)" 

Другие решения

1)

 if(floor($number) == $number) { // Currently most upvoted solution: 

тесты:

 $number = true; var_dump(floor($number) == $number); // prints "bool(true)" which is incorrect. 

2)

 if (is_numeric($number) && floor($number) == $number) { 

Угловой корпус:

 $number = "0x539"; var_dump(is_numeric($number) && floor($number) == $number); // prints "bool(true)" which depend on context may or may not be what you want 

3)

 if (ctype_digit($number)) { 

тесты:

 var_dump(ctype_digit("0x539")); // prints "bool(false)" var_dump(ctype_digit(10)); // prints "bool(false)" var_dump(ctype_digit(0x53)); // prints "bool(false)" 
 if(floor($number) == $number) 

Не является стабильным алгоритмом. Когда значение математически 1,0, числовое значение может быть 0.9999999. Если вы примените floor (), то это будет 0, что не равно 0.9999999.

Вы должны угадать прецизионный радиус, например, 3 цифры

 if(round($number,3) == round($number)) 
 (string)floor($pecahformat[3])!=(string)$pecahformat[3] 

Я тестировал все предлагаемые решения со многими упомянутыми проблемными значениями, все они терпят неудачу, по крайней мере, для одного из тестовых случаев. Начните проверять, является ли $value числом с использованием is_numeric($value) уменьшает количество отказов для многих решений, но не превращает какое-либо решение в конечное:

 $test_cases = array(0.29, 2, 6, 2.33, 6.2, '10.00', 1.4, 10, "10", 10.5, "0x539", true, false, 0x53, 9.4, "ten", "100", 1, 0.999999997, 0, 0.0001, 1.0, 0.9999999, (-(4.42-5))/0.29); function is_whole_number($value) { // Doing this prevents failing for values like true or "ten" if (!is_numeric($value)) { return false; } // @ghostdog74's solution fails for "10.00" // return (ctype_digit((string) $value)); // Both @Maurice's solutions fails for "10.00" // return ((string) $value === (string) (int) $value); // return is_int($value); // @j.hull's solution always returns true for numeric values // return (abs($value) % 1 == 0 ? true : false); // @ MartyIX's solution fails for "10.00" // return ($value === intval($value)); // This one fails for (-(4.42-5))/0.29 // return (floor($value) == $value); // This one fails for 2 // return ctype_digit($value); // I didn't understand Josh Crozier's answer // @joseph4tw's solution fails for (-(4.42-5))/0.29 // return !(fmod($value, 1) != 0); // If you are unsure about the double negation, doing this way produces the same // results: // return (fmod($value, 1) == 0); // Doing this way, it always returns false // return (fmod($value, 1) === 0); // @Anthony's solution fails for "10.00" // return (is_numeric($value) && is_int($value)); // @Aistina's solution fails for 0.999999997 // return (abs($value - round($value)) < 0.0001); // @Notinlist's solution fails for 0.999999997 // return (round($value, 3) == round($value)); } foreach ($test_cases as $test_case) { var_dump($test_case); echo ' is a whole number? '; echo is_whole_number($test_case) ? 'yes' : 'no'; echo "\n"; } 

Я думаю, что такие решения, как предложенные @Aistina и @Notinlist, являются лучшими, потому что они используют порог ошибки, чтобы определить, является ли значение целым числом. Важно отметить, что они работали как ожидалось для выражения (-(4.42-5))/0.29 , в то время как все остальные проваливались в этом тестовом случае.

Я решил использовать решение @ Notinlist из-за его удобочитаемости:

 function is_whole_number($value) { return (is_numeric($value) && (round($value, 3) == round($value))); } 

Мне нужно проверить, являются ли значения целыми числами, валютой или процентом, я думаю, что двух цифр точности достаточно, поэтому решение @ Notinlist соответствует моим потребностям.

Выполнение этого теста:

 $test_cases = array(0.29, 2, 6, 2.33, 6.2, '10.00', 1.4, 10, "10", 10.5, "0x539", true, false, 0x53, 9.4, "ten", "100", 1, 0.999999997, 0, 0.0001, 1.0, 0.9999999, (-(4.42-5))/0.29); function is_whole_number($value) { return (is_numeric($value) && (round($value, 3) == round($value))); } foreach ($test_cases as $test_case) { var_dump($test_case); echo ' is a whole number? '; echo is_whole_number($test_case) ? 'yes' : 'no'; echo "\n"; } 

Производит следующий вывод:

 float(0.29) is a whole number? no int(2) is a whole number? yes int(6) is a whole number? yes float(2.33) is a whole number? no float(6.2) is a whole number? no string(5) "10.00" is a whole number? yes float(1.4) is a whole number? no int(10) is a whole number? yes string(2) "10" is a whole number? yes float(10.5) is a whole number? no string(5) "0x539" is a whole number? yes bool(true) is a whole number? no bool(false) is a whole number? no int(83) is a whole number? yes float(9.4) is a whole number? no string(3) "ten" is a whole number? no string(3) "100" is a whole number? yes int(1) is a whole number? yes float(0.999999997) is a whole number? yes int(0) is a whole number? yes float(0.0001) is a whole number? yes float(1) is a whole number? yes float(0.9999999) is a whole number? yes float(2) is a whole number? yes 
 floor($entityElementCount) == $entityElementCount 

Это будет верно, если это целое число

Казалось бы, простой подход заключается в использовании модуля (%), чтобы определить, является ли значение целым или нет.

 x = y % 1 

если y – любое другое, то целое число, результат не равен нулю (0). Тогда будет проходить тест:

 if (y % 1 == 0) { // this is a whole number } else { // this is not a whole number } var isWhole = (y % 1 == 0? true: false); // to get a boolean return. 

Предположим, что это будет рассматривать отрицательное число как целое число, а затем просто оберните ABS () вокруг y чтобы всегда проверять положительное.

Я всегда использую typecasting, чтобы проверить, содержит ли переменные целое число, удобно, когда вы не знаете происхождения или типа значения.

 if ((string) $var === (string) (int) $var) { echo 'whole number'; } else { echo 'whatever it is, it\'s something else'; } 

В вашем конкретном случае я бы использовал is_int ()

 if (is_int($var) { echo 'integer'; } 

Простое решение только для положительных целых чисел. Это может не работать для всего.

 $string = '0x539'; $ceil = ceil($string); if($ceil < 1){ $ceil = FALSE; // or whatever you want ie 0 or 1 } echo $ceil; // 1337 

При желании вы можете использовать floor () вместо ceil ().

 function isInteger($value) { // '1' + 0 == int, '1.2' + 0 == float, '1e2' == float return is_numeric($value) && is_int($value + 0); } function isWholeNumber($value) { return is_numeric($value) && (is_int($value + 0) || (intval($value + 0) === intval(ceil($value + 0)))); } 

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

 if (isInteger($foo)) { // integer as int or string } if (isWholeNumber($foo)) { // integer as int or string, or float/double with zero decimal part } else if (is_numeric($foo)) { // decimal number - still numeric, but not int } 

Это правильно проверит ваш номер, не округляя его, переведя его на int (который в случае десятичного числа потеряет десятичную часть) или выполнит какую-либо математику. Если, однако, вы хотите лечить 1.00 как целое число, то это еще одна история.