Max Chandler
Max Chandler

Reputation: 513

Whole number or decimal number

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

Answers (10)

Nabeel Khan
Nabeel Khan

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

EdieBou
EdieBou

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

NickSoft
NickSoft

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

Daan
Daan

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

despotbg
despotbg

Reputation: 778

Maybe this is most elegant solution:

if ( $answer3 != (int) ( $answer3 ) ) {

Upvotes: 2

vrijdenker
vrijdenker

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

Galen
Galen

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

Wrikken
Wrikken

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

peacemaker
peacemaker

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

Alix Axel
Alix Axel

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

Related Questions