PHP check if variable is a whole number

Viewed 51920

I have this PHP code:

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

What i want to know is, how to check whether $entityElementCount is a whole number (2, 6, ...) or partial (2.33, 6.2, ...).

Thank you!

21 Answers
if (floor($number) == $number)
$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";
}

The basic way, as Chacha said is

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

However, floating point types cannot accurately store numbers, which means that 1 might be stored as 0.999999997. This will of course mean the above check will fail, because it will be rounded down to 0, even though for your purposes it is close enough to 1 to be considered a whole number. Therefore try something like this:

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

If you know that it will be numeric (meaning it won't ever be a an integer cast as a string, like "ten" or "100", you can just use is_int():

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

echo ($entityWholeNumber) ? "Whole Number!" : "Not a whole number!";
if(floor($number) == $number)

Is not a stable algorithm. When a value is matematically 1.0 the numerical value can be 0.9999999. If you apply floor() on it it will be 0 which is not equals to 0.9999999.

You have to guess a precision radius for example 3 digits

if(round($number,3) == round($number))
    $num = 2.0000000000001;
    if( $num == floor( $num  ) ){
        echo('whole');
    }else{
        echo('fraction');
    }

EX:

2.0000000000001 | fraction

2.1 | fraction

2.00 | whole

2 | whole

Another hacky way I came up with is ceil($value) === floor($value). If a number is a whole number, this should always be true, even if comparing 10 with 10.000 and will even work with numbers cast in string, for example ceil("10.0") === floor(10).

floor($entityElementCount) == $entityElementCount

This will be true if this is a whole number

This is not an attempt to answer this question so much. Their are plenty of answer already. If you are doing statistics as the question implies I suspect @antonio-vinicius-menezes-medei answer will suite you best. However I needed this answer for input validation. I found this check more reliable for validating an input string is a whole number:

is_numeric($number) && preg_match('/^[0-9]+$/', $number)

The 'is_numeric' simply corrects for "true" converting to "1" in preg_match.

So playing off of @antonio-vinicius-menezes-medei answer. I wrote a script to test this below. Note the ini_set('precision', 20). preg_match will convert the argument to a string. If your precicion is set below the length of the float values they will simply round at the given precision. Similar to @antonio-vinicius-menezes-medei answer this precision setting will force a similar estimation length.

  ini_set('precision', 20);
  $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);

  foreach ($test_cases as $number)
  {
    echo '<strong>';
    var_dump($number);
    echo '</strong>';
    echo boolFormater(is_numeric($number) && preg_match('/^[0-9]+$/', $number));
    echo '<br>';
  }

  function boolFormater($value)
  {
    if ($value)
    {
      return 'Yes';
    }
    return 'No';
  }

Which produces this output:

float(0.28999999999999998002) No
int(2) Yes
int(6) Yes
float(2.3300000000000000711) No
float(6.2000000000000001776) No
string(5) "10.00" No
float(1.3999999999999999112) No
int(10) Yes
string(2) "10" Yes
float(10.5) No
string(5) "0x539" No
bool(true) No
bool(false) No
int(83) Yes
float(9.4000000000000003553) No
string(3) "ten" No
string(3) "100" Yes
int(1) Yes
float(0.99999999699999997382) No
int(0) Yes
float(0.00010000000000000000479) No
float(1) Yes
float(0.99999990000000005264) No
float(2.0000000000000004441) No

improved version of @Tyler Carter's solution, which handles edge cases better than the original:

function is_whole_number($number){
    return (is_float(($f=filter_var($number,FILTER_VALIDATE_FLOAT))) && floor($f)===$f);    
}

(Tyler's code fail to recognize that the string "123foobar" is not a whole number. this improved version won't make that mistake. credits to @Shafizadeh in the comments for discovering the bug. also this is php7 strict_types=1-compatible)

I know this is a super old post but this is a simple function that will return a valid whole number and cast it to an int. Returns false if it fails.

function isWholeNumber($v)
{
    if ($v !='' && is_numeric($v) && strpos($v, '.') === false) {
        return (int)$v;
    }
    return false;
}

Usage :

$a = 43;
$b = 4.3;
$c = 'four_three';

isWholeNumber($a) // 43
isWholeNumber($b) // false
isWholeNumber($c) // false

Just to share my solution with localized string/number, this combo worked like a charm for me.

public static function isWholeNumber ($input, $decimalDelimiter = ',')
{
    if (is_string($input)){
        $input = str_replace($decimalDelimiter, '.', $input);
        $input = floatval($input);
    }

    if (fmod($input,1) !== 0.0) {
        return false;
    }

    return true;
}
$entityElementCount = (-($highScore-$totalKeywordCount))/0.29;

Method 1-
    By using ctype_digit() function. 

    if ( ctype_digit($entityElementCount )) { 
        echo "Whole Number\n"; 
    } else { 
        echo "Not a whole Number\n"; 
    } 


Method 2-
    By using is_float() function. 

    if (is_float($entityElementCount )) { 
        echo "Not a Whole Number\n"; 
    } else { 
        echo "Whole Number\n"; 
    } 


Method 3-
    By using is_int() function. 

    if (is_int($entityElementCount )) { 
        echo "Whole Number\n"; 
    } else { 
        echo "Not a whole Number\n"; 
    } 


Method 5-
    By using fmod() function. 

    It needs 2 parameters one dividend and other is divisor
    Here $dividend=$entityElementCount and divisor=1
    if (fmod($dividend,$divisor) !== 0.0) {
        echo 'Not a whole number!';
    } else {
     echo 'A whole number!';
    }

there are some more function like intval(), floor(),... can be used to check it`enter code here`
Related