Reputation: 513
I'm looking for a function that tests to see if an integer is a whole number. So far I've got this:
if (is_numeric($answer3)) {
echo "Is triangular\n";
} else {
echo "Is not triangular\n";
}
But this always returns "Is triangular", even when $answer3 is a decimal.
How can I test an integer to see if it has a decimal?
Upvotes: 14
Views: 24168
Reputation: 3993
try this
if(!is_numeric($nabtron) || $nabtron != floor($nabtron) || $nabtron < 0){
echo "it's not numeric or is a float or a negative number";
}
or in case you need positive results:
if(is_numeric($nabtron) && $nabtron == floor($nabtron) && $nabtron < 0){
echo "it's numeric and not a float and is zero or positive number";
}
Upvotes: -1
Reputation: 1
I'm a fully new in this, but I figure it out that best way to check if a number is float or integer in PHP is by simple check:
if ($number == round($number)) { } else { }
If it's truly a integer it will be equal.
Upvotes: 0
Reputation: 3335
I checked all the answers and there were few trying to check for the floating part. That's the correct way to do, except that it's not a good idea to compare floating point numbers using equal sign. Best solution would be:
function isIntegerNumber($number){
$floor = floor($number);
$fract = abs($number - $floor);
return is_numeric($number) && $fract < 1e-16;
}
echo var_export(isIntegerNumber("10X"), true).PHP_EOL;
echo var_export(isIntegerNumber("3.0001"), true).PHP_EOL;
echo var_export(isIntegerNumber("-23.0001"), true).PHP_EOL;
echo var_export(isIntegerNumber(-10.01), true).PHP_EOL;
echo var_export(isIntegerNumber("3.00"), true).PHP_EOL;
echo var_export(isIntegerNumber("-23.00"), true).PHP_EOL;
echo var_export(isIntegerNumber(-10.00), true).PHP_EOL;
echo var_export(isIntegerNumber(5), true).PHP_EOL;
echo var_export(isIntegerNumber(-5), true).PHP_EOL;
$tricky = (0.1+0.7)*10.0;
echo "now something a bit tricky: ".PHP_EOL;
echo "(0.1+0.7)*10.0 = ".var_export($tricky, true) .' (type: "'.gettype($tricky).'")'.PHP_EOL;
echo 'is it int: '.var_export(isIntegerNumber($tricky), true).PHP_EOL;
echo 'is it 8: '.var_export($tricky == 8, true).PHP_EOL;
result:
false
false
false
false
true
true
true
true
true
now something a bit tricky:
(0.1+0.7)*10.0 = 7.9999999999999991 (type: "double")
is it int: false
is it 8: false
Upvotes: 1
Reputation: 7925
This function does the job for 99% of the time for every input you throw in:
function($number) {
(float)(int)$number == (float)$number;
}
Note: Strict comparison is not really necessary here, because when casting to (float) both are always the same type.
Inspired by this article about PHP insanity when comparing values, I ran a little test for the following inputs:
As expected
These values do not have a fractional part:
1.0 // TRUE
'1.0' // TRUE
true // TRUE
false // TRUE
'true' // TRUE
'false' // TRUE
10e3 // TRUE
0123 // TRUE
null // TRUE
'test' // TRUE
1 // TRUE
0 // TRUE
1.2e3 // TRUE
0xfe // TRUE
0b0 // TRUE
0b1 // TRUE
b0 // TRUE
b1 // TRUE
-0xfe // TRUE
'' // TRUE
'8bottles' // TRUE
'8.0bottles' // TRUE
'0foo' // TRUE
array() // TRUE
'0x12foo' // TRUE
'0123' // TRUE
'0xfe' // TRUE
new Object // TRUE
These values do have a fractional part:
'1.1' // FALSE
1.1 // FALSE
10e-3 // FALSE
.9 // FALSE
0.9 // FALSE
.1 // FALSE
0.1 // FALSE
0123.2 // FALSE
7E-10 // FALSE
1.2e-3 // FALSE
Not expected:
'8e2bottles' // FALSE
As explained in the article, this value will do crazy stuff and will also fail in my function. It's because casting to int
and float
gives a total different value. So be prepared!
(int)'8e2bottles' // 8
(float)'8e2bottles' // 800.0
Upvotes: 1
Reputation: 778
Maybe this is most elegant solution:
if ( $answer3 != (int) ( $answer3 ) ) {
Upvotes: 2
Reputation: 1431
I've tried several answers (from other pages as well), but what worked best in my case is this:
$number = floatval($number);
if ($number == round($number)) {
// Number does not have decimals (or .00000)
}else{
// Number does have decimals
}
Upvotes: 2
Reputation: 30170
is_numeric will return true for floats too, considering floats are numeric
Finds whether the given variable is numeric. Numeric strings consist of optional sign, any number of digits, optional decimal part and optional exponential part. Thus +0123.45e6 is a valid numeric value. Hexadecimal notation (0xFF) is allowed too but only without sign, decimal and exponential part.
You can try is_float(), but if the input is a string it wont work.
var_dump( is_float( '23.5' ) ); // return false
So if you are dealing with something that is a string representation of a number then just look for a .
if ( strpos( $answer3, '.' ) === false )
You can add is_numeric if you need to
// Make sure its numeric and has no decimal point
if ( is_numeric( $answer3 ) && strpos( $answer3, '.' ) === false )
Upvotes: 18
Reputation: 70460
is_int
if you also need it to be of the type integer,ctype_digit
if you are testing strings,filter_var($input,FILTER_VALIDATE_INT)
for all.And search the manual
Upvotes: 4
Reputation: 2591
If $answer3 isn't a string, you can try using:
is_float()
to see if is a floating point value, rather than just a numeric value.
Upvotes: 1
Reputation: 154513
Should 10.0
be considered as an integer or a float? If integer, you're looking for fmod()
:
if (fmod($number, 1) == 0) // $number DOES NOT have a significant decimal part
{
// is whole number
}
Otherwise, is_int()
suffices.
EDIT: Another way to check for insignificant decimal part would be:
if (round($number, 0) == $number)
{
// is whole number
}
Upvotes: 16