Related
I have a function that calculates a value, which is a float:
function crunch (float $a, float $b):float
{
//do stuff
return $result;
}
function testSomething (float $a, float $b):bool
{
//if $result is -0 that returns false
$result = crunch($a, $b);
return $result === 0;
}
Why is -0 not equal to 0 and how can if safely check if that number is zero, assuming that 0 should be the same as -0?
UPDATE
Since there was the question for more details. I have a class Vec2 which has x() and y() getters, and a method called cross, which looks like that:
public function cross(Vec2 $vec2):float
{
return ($this->_x * $vec2->_y) - ($vec2->_x * $this->_y);
}
Running this code:
$cross = $this->cross($d);
results in that debugger output
and $cross === 0 evaluates to false;
Cast the 0 to float. It's probably failing because 0 as literal is an int, and the result is a float, so === is false because of types.
At least doing something like this, fails like your case (the result is false):
php -r '$a = (float) -0; $b = 0; echo ($a === $b);'
The result is true in this case:
php -r '$a = (float) -0; $b = (float) 0; echo ($a == $b);'
Negative zero isn't a thing. But a negative value smaller than the configured precision for floating point display is.
You can't reliably check direct equivalence between two floats, you can only reasonably check that the difference between two floats is smaller than you care about for a given calculation.
eg:
function float_equiv(float $a, float $b, float $epsilon=NULL) {
// default to PHP's configured display precision
$epsilon = $epsilon ?: pow(10, -1*ini_get('precision'));
if( abs($a - $b) < $epsilon ) {
return true;
}
return false;
}
Just to illustrate the accepted answer by #monstercode
Math logic and computer logic are separated entities.
We intuitively know that -0 = 0 but in computer terms the sign of a number is stored separately from the number (like a meta data) - this is what floats do.
In that case an integer is compared to a float.
$result_1 = 1234*0;// remains an integer
$result_2 = -1234*0;// remains an integer
$result_3 = -1.234*0;// becomes a float
$result_4 = 1.234*0; // becomes a float
var_dump($result_1 === 0); // true
var_dump($result_2 === 0); // true
var_dump($result_3 === 0); // false
var_dump($result_4 === 0); // false
I need to check in PHP if user entered a decimal number (US way, with decimal point: X.XXX)
Any reliable way to do this?
You can get most of what you want from is_float, but if you really need to know whether it has a decimal in it, your function above isn't terribly far (albeit the wrong language):
function is_decimal( $val )
{
return is_numeric( $val ) && floor( $val ) != $val;
}
if you want "10.00" to return true check Night Owl's answer
If you want to know if the decimals has a value you can use this answer.
Works with all kind of types (int, float, string)
if(fmod($val, 1) !== 0.00){
// your code if its decimals has a value
} else {
// your code if the decimals are .00, or is an integer
}
Examples:
(fmod(1.00, 1) !== 0.00) // returns false
(fmod(2, 1) !== 0.00) // returns false
(fmod(3.01, 1) !== 0.00) // returns true
(fmod(4.33333, 1) !== 0.00) // returns true
(fmod(5.00000, 1) !== 0.00) // returns false
(fmod('6.50', 1) !== 0.00) // returns true
Explanation:
fmod returns the floating point remainder (modulo) of the division of the arguments, (hence the (!== 0.00))
Modulus operator - why not use the modulus operator? E.g. ($val % 1 != 0)
From the PHP docs:
Operands of modulus are converted to integers (by stripping the decimal part) before processing.
Which will effectively destroys the op purpose, in other languages like javascript you can use the modulus operator
If all you need to know is whether a decimal point exists in a variable then this will get the job done...
function containsDecimal( $value ) {
if ( strpos( $value, "." ) !== false ) {
return true;
}
return false;
}
This isn't a very elegant solution but it works with strings and floats.
Make sure to use !== and not != in the strpos test or you will get incorrect results.
another way to solve this: preg_match('/^\d+\.\d+$/',$number); :)
The function you posted is just not PHP.
Have a look at is_float [docs].
Edit: I missed the "user entered value" part. In this case you can actually use a regular expression:
^\d+\.\d+$
I was passed a string, and wanted to know if it was a decimal or not. I ended up with this:
function isDecimal($value)
{
return ((float) $value !== floor($value));
}
I ran a bunch of test including decimals and non-decimals on both sides of zero, and it seemed to work.
is_numeric returns true for decimals and integers. So if your user lazily enters 1 instead of 1.00 it will still return true:
echo is_numeric(1); // true
echo is_numeric(1.00); // true
You may wish to convert the integer to a decimal with PHP, or let your database do it for you.
This is a more tolerate way to handle this with user input. This regex will match both "100" or "100.1" but doesn't allow for negative numbers.
/^(\d+)(\.\d+)?$/
// if numeric
if (is_numeric($field)) {
$whole = floor($field);
$fraction = $field - $whole;
// if decimal
if ($fraction > 0)
// do sth
else
// if integer
// do sth
}
else
// if non-numeric
// do sth
i use this:
function is_decimal ($price){
$value= trim($price); // trim space keys
$value= is_numeric($value); // validate numeric and numeric string, e.g., 12.00, 1e00, 123; but not -123
$value= preg_match('/^\d$/', $value); // only allow any digit e.g., 0,1,2,3,4,5,6,7,8,9. This will eliminate the numeric string, e.g., 1e00
$value= round($value, 2); // to a specified number of decimal places.e.g., 1.12345=> 1.12
return $value;
}
$lat = '-25.3654';
if(preg_match('/./',$lat)) {
echo "\nYes its a decimal value\n";
}
else{
echo 'No its not a decimal value';
}
A total cludge.. but hey it works !
$numpart = explode(".", $sumnum);
if ((exists($numpart[1]) && ($numpart[1] > 0 )){
// it's a decimal that is greater than zero
} else {
// its not a decimal, or the decimal is zero
}
the easy way to find either posted value is integer and float so this will help you
$postedValue = $this->input->post('value');
if(is_numeric( $postedValue ) && floor( $postedValue ))
{
echo 'success';
}
else
{
echo 'unsuccess';
}
if you give 10 or 10.5 or 10.0 the result will be success if you define any character or specail character without dot it will give unsuccess
How about (int)$value != $value?
If true it's decimal, if false it's not.
I can't comment, but I have this interesting behaviour.
(tested on v. 7.3.19 on a website for php testing online)
If you multiply 50 by 1.1 fmod gives different results than expected.
If you do by 1.2 or 1.3 it's fine, if you do another number (like 60 or 40) is also fine.
$price = 50;
$price = $price * 1.1;
if(strpos($price,".") !== false){
echo "decimal";
}else{
echo "not a decimal";
}
echo '<br />';
if(fmod($price, 1) !== 0.00){
//echo fmod($price, 1);
echo "decimal";
} else {
echo "not a decimal";
}//end if
Simplest solution is
if(is_float(2.3)){
echo 'true';
}
If you are working with form validation. Then in this case form send string.
I used following code to check either form input is a decimal number or not.
I hope this will work for you too.
function is_decimal($input = '') {
$alphabets = str_split($input);
$find = array('0','1','2','3','4','5','6','7','8','9','.'); // Please note: All intiger numbers are decimal. If you want to check numbers without point "." then you can remove '.' from array.
foreach ($alphabets as $key => $alphabet) {
if (!in_array($alphabet, $find)) {
return false;
}
}
// Check if user has enter "." point more then once.
if (substr_count($input, ".") > 1) {
return false;
}
return true;
}
function is_decimal_value( $a ) {
$d=0; $i=0;
$b= str_split(trim($a.""));
foreach ( $b as $c ) {
if ( $i==0 && strpos($c,"-") ) continue;
$i++;
if ( is_numeric($c) ) continue;
if ( stripos($c,".") === 0 ) {
$d++;
if ( $d > 1 ) return FALSE;
else continue;
} else
return FALSE;
}
return TRUE;
}
Known Issues with the above function:
1) Does not support "scientific notation" (1.23E-123), fiscal (leading $ or other) or "Trailing f" (C++ style floats) or "trailing currency" (USD, GBP etc)
2) False positive on string filenames that match a decimal: Please note that for example "10.0" as a filename cannot be distinguished from the decimal, so if you are attempting to detect a type from a string alone, and a filename matches a decimal name and has no path included, it will be impossible to discern.
Maybe try looking into this as well
!is_int()
This question already has answers here:
Test if number is odd or even
(20 answers)
Closed 7 years ago.
How can I get if a number is even or odd or neither (have decimal, like 1.5) with PHP? I know that there are operators like *, /, but they did not work.
Here's a try (of course it did not) (work that's just to find if it's a even number):
function even($n) {
return (($n/2)*2 == $n);
}
echo even(1); // true (should be false)
echo even(2); // true
How about
function even($n) {
if (!is_int($n)) {return 'n';}
return !($n % 2);
}
even(1); // false;
even(2); // true;
even(1.5); // 'n'
The danger here is that 'n' will evaluate as false if used as a boolean. It might be better to return some specific constants instead of true or false. The OP didn't specify what the return values should be.
It is pretty simple. modulo (%) is the operator you want, it determines if there would be a remainder if x is divided by y... for example (3 % 2 = 1) and (4 % 2 = 0).
This has been asked before too - pretty common question - you really just need to see if your number, $n % 2 is equal to 0.
php test if number is odd or even
Check if given number is integer first. And bitwise & to check if it is even or odd. Here is an example...
if (is_int($n)) {
if ($n & 1) {
echo 'Odd!';
} else {
echo 'Even!';
}
} else {
echo "Not a Integer!";
}
Hope this is helpful.
Use the modulo operator (%) to determine whether the integer is divisible by 2. You also need abs() to handle negative numbers, and is_int() to handle the fact that the modulo operator doesn't correctly handle floating point numbers. An example implementation follows:
function is_even($num) {
return is_int($num) && abs($num % 2) == 0;
}
function is_odd($num) {
return is_int($num) && abs($num % 2) == 1;
}
// this last one seems self-explanatory, but if you want it, here it is
function is_neither_even_nor_odd($num) {
return !is_even($num) && !is_odd($num);
}
// Tests: The following should all output true:
var_dump(
is_even(0),
is_even(2),
is_even(-6),
is_even(51238238),
is_odd(1),
is_odd(-1),
is_odd(57),
is_neither_even_nor_odd(1.5),
is_neither_even_nor_odd(2.5),
is_neither_even_nor_odd(-0.5),
is_neither_even_nor_odd(0.00000001)
);
Here's a demo.
is_numeric returns true if the given variable is a number
is_int returns true if the given variable is an integer
The modulor operator % can be used to determine if an integer is even or odd:
$num % 2 == 0 // returns true if even, false if odd
I need to check in PHP if user entered a decimal number (US way, with decimal point: X.XXX)
Any reliable way to do this?
You can get most of what you want from is_float, but if you really need to know whether it has a decimal in it, your function above isn't terribly far (albeit the wrong language):
function is_decimal( $val )
{
return is_numeric( $val ) && floor( $val ) != $val;
}
if you want "10.00" to return true check Night Owl's answer
If you want to know if the decimals has a value you can use this answer.
Works with all kind of types (int, float, string)
if(fmod($val, 1) !== 0.00){
// your code if its decimals has a value
} else {
// your code if the decimals are .00, or is an integer
}
Examples:
(fmod(1.00, 1) !== 0.00) // returns false
(fmod(2, 1) !== 0.00) // returns false
(fmod(3.01, 1) !== 0.00) // returns true
(fmod(4.33333, 1) !== 0.00) // returns true
(fmod(5.00000, 1) !== 0.00) // returns false
(fmod('6.50', 1) !== 0.00) // returns true
Explanation:
fmod returns the floating point remainder (modulo) of the division of the arguments, (hence the (!== 0.00))
Modulus operator - why not use the modulus operator? E.g. ($val % 1 != 0)
From the PHP docs:
Operands of modulus are converted to integers (by stripping the decimal part) before processing.
Which will effectively destroys the op purpose, in other languages like javascript you can use the modulus operator
If all you need to know is whether a decimal point exists in a variable then this will get the job done...
function containsDecimal( $value ) {
if ( strpos( $value, "." ) !== false ) {
return true;
}
return false;
}
This isn't a very elegant solution but it works with strings and floats.
Make sure to use !== and not != in the strpos test or you will get incorrect results.
another way to solve this: preg_match('/^\d+\.\d+$/',$number); :)
The function you posted is just not PHP.
Have a look at is_float [docs].
Edit: I missed the "user entered value" part. In this case you can actually use a regular expression:
^\d+\.\d+$
I was passed a string, and wanted to know if it was a decimal or not. I ended up with this:
function isDecimal($value)
{
return ((float) $value !== floor($value));
}
I ran a bunch of test including decimals and non-decimals on both sides of zero, and it seemed to work.
is_numeric returns true for decimals and integers. So if your user lazily enters 1 instead of 1.00 it will still return true:
echo is_numeric(1); // true
echo is_numeric(1.00); // true
You may wish to convert the integer to a decimal with PHP, or let your database do it for you.
This is a more tolerate way to handle this with user input. This regex will match both "100" or "100.1" but doesn't allow for negative numbers.
/^(\d+)(\.\d+)?$/
// if numeric
if (is_numeric($field)) {
$whole = floor($field);
$fraction = $field - $whole;
// if decimal
if ($fraction > 0)
// do sth
else
// if integer
// do sth
}
else
// if non-numeric
// do sth
i use this:
function is_decimal ($price){
$value= trim($price); // trim space keys
$value= is_numeric($value); // validate numeric and numeric string, e.g., 12.00, 1e00, 123; but not -123
$value= preg_match('/^\d$/', $value); // only allow any digit e.g., 0,1,2,3,4,5,6,7,8,9. This will eliminate the numeric string, e.g., 1e00
$value= round($value, 2); // to a specified number of decimal places.e.g., 1.12345=> 1.12
return $value;
}
$lat = '-25.3654';
if(preg_match('/./',$lat)) {
echo "\nYes its a decimal value\n";
}
else{
echo 'No its not a decimal value';
}
A total cludge.. but hey it works !
$numpart = explode(".", $sumnum);
if ((exists($numpart[1]) && ($numpart[1] > 0 )){
// it's a decimal that is greater than zero
} else {
// its not a decimal, or the decimal is zero
}
the easy way to find either posted value is integer and float so this will help you
$postedValue = $this->input->post('value');
if(is_numeric( $postedValue ) && floor( $postedValue ))
{
echo 'success';
}
else
{
echo 'unsuccess';
}
if you give 10 or 10.5 or 10.0 the result will be success if you define any character or specail character without dot it will give unsuccess
How about (int)$value != $value?
If true it's decimal, if false it's not.
I can't comment, but I have this interesting behaviour.
(tested on v. 7.3.19 on a website for php testing online)
If you multiply 50 by 1.1 fmod gives different results than expected.
If you do by 1.2 or 1.3 it's fine, if you do another number (like 60 or 40) is also fine.
$price = 50;
$price = $price * 1.1;
if(strpos($price,".") !== false){
echo "decimal";
}else{
echo "not a decimal";
}
echo '<br />';
if(fmod($price, 1) !== 0.00){
//echo fmod($price, 1);
echo "decimal";
} else {
echo "not a decimal";
}//end if
Simplest solution is
if(is_float(2.3)){
echo 'true';
}
If you are working with form validation. Then in this case form send string.
I used following code to check either form input is a decimal number or not.
I hope this will work for you too.
function is_decimal($input = '') {
$alphabets = str_split($input);
$find = array('0','1','2','3','4','5','6','7','8','9','.'); // Please note: All intiger numbers are decimal. If you want to check numbers without point "." then you can remove '.' from array.
foreach ($alphabets as $key => $alphabet) {
if (!in_array($alphabet, $find)) {
return false;
}
}
// Check if user has enter "." point more then once.
if (substr_count($input, ".") > 1) {
return false;
}
return true;
}
function is_decimal_value( $a ) {
$d=0; $i=0;
$b= str_split(trim($a.""));
foreach ( $b as $c ) {
if ( $i==0 && strpos($c,"-") ) continue;
$i++;
if ( is_numeric($c) ) continue;
if ( stripos($c,".") === 0 ) {
$d++;
if ( $d > 1 ) return FALSE;
else continue;
} else
return FALSE;
}
return TRUE;
}
Known Issues with the above function:
1) Does not support "scientific notation" (1.23E-123), fiscal (leading $ or other) or "Trailing f" (C++ style floats) or "trailing currency" (USD, GBP etc)
2) False positive on string filenames that match a decimal: Please note that for example "10.0" as a filename cannot be distinguished from the decimal, so if you are attempting to detect a type from a string alone, and a filename matches a decimal name and has no path included, it will be impossible to discern.
Maybe try looking into this as well
!is_int()
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!
if (floor($number) == $number)
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
$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";
}
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)"
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!";
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
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).
(string)floor($pecahformat[3])!=(string)$pecahformat[3]
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)
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.
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';
}
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.
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.
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`