PHP check if variable is a whole number

隐身守侯 提交于 2019-12-03 19:17:07

问题


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!


回答1:


$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";
}



回答2:


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



回答3:


I know this is old, but I thought I'd share something I just found:

Use fmod and check for 0

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

fmod is different from % because if you have a fraction, % doesn't seem to work for me (it returns 0...for example, echo 9.4 % 1; will output 0). With fmod, you'll get the fraction portion. For example:

echo fmod(9.4, 1);

Will output 0.4




回答4:


I would use intval function like this:

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

}

Tests:

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)"

Other solutions

1)

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

Tests:

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

2)

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

Corner case:

$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)) {

Tests:

var_dump(ctype_digit("0x539")); // prints "bool(false)"
var_dump(ctype_digit(10)); // prints "bool(false)"
var_dump(ctype_digit(0x53)); // prints "bool(false)"



回答5:


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)



回答6:


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!";



回答7:


I tested all the proposed solutions with many problematic values mentioned, they all fail for at least one of the test cases. Start checking if $value is a number using is_numeric($value) reduces the number of failures for many solutions, but does not turn any solution into an ultimate one:

$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";
}

I think that solutions like the ones proposed by @Aistina and @Notinlist are the best ones, because they use an error threshold to decide whether a value is a whole number. It is important to note that they worked as expected for the expression (-(4.42-5))/0.29, while all the others failed in that test case.

I decided to use @Notinlist's solution because of its readability:

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

I need to test if values are whole numbers, currency or percentage, I think 2 digits of precision is enough, so @Notinlist's solution fits my needs.

Running this test:

$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";
}

Produces the following output:

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



回答8:


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



回答9:


(string)floor($pecahformat[3])!=(string)$pecahformat[3]



回答10:


floor($entityElementCount) == $entityElementCount

This will be true if this is a whole number




回答11:


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




回答12:


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)




回答13:


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

EX:

2.0000000000001 | fraction

2.1 | fraction

2.00 | whole

2 | whole




回答14:


What seems a simple approach would be to use modulus (%) to determine if a value is whole or not.

x = y % 1  

if y is anything other then a whole number the result is not a zero (0). A test then would be:

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. 

Granted this will view a negative number as a whole number, then then just wrap ABS() around y to always test on the positive.




回答15:


I always use typecasting to check if variables contain a whole number, handy when you don't know the origin or type of the value.

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

In your particular case, I would use is_int()

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



回答16:


A simple solution for positive whole numbers only. This may not work for everything.

$string = '0x539';
$ceil = ceil($string);

if($ceil < 1){
  $ceil = FALSE; // or whatever you want i.e 0 or 1
}

echo $ceil; // 1337

You can use floor() instead of ceil() if so desired.




回答17:


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 you want to check for both whole and decimal numbers, you can do the following:

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
}

This will correctly check your number without rounding it, casting it to int (which in the case of a decimal number will lose the decimal part), or doing any math. If, however, you want to treat 1.00 as a whole number, then that's a whole another story.




回答18:


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



回答19:


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



回答20:


$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`


来源:https://stackoverflow.com/questions/2188675/php-check-if-variable-is-a-whole-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!