Types7 min readExamples run on PHP 8.5.10

is_float()

Learn how PHP 8.4 is_float() tests whether a value has the float type, why numeric strings and integers fail, and how to avoid common mistakes.

Signature

is_float(mixed $value): bool

Purpose

is_float() answers one narrow question: is the type of this value float? It looks at the type the value currently has, not at what the value looks like or whether it could be converted. It is useful at boundaries where data of mixed type arrives, such as decoded JSON, results of calculations, or arguments to a function that accepts mixed.

Signature

Parameters and defaults

$value is the only parameter. It accepts any PHP value (integer, string, array, object, null, and so on) and has no default, so you must always pass it. The function never modifies the value.

Return value and failure cases

The function returns true when the value is of type float and false for everything else. It does not throw for unusual input and does not emit warnings, so there is no failure mode to handle. Passing an unusual type simply gives false.

If you need to know whether input is a number or a numeric string, for instance text from a form, use is_numeric() instead. Form input is always a string, so is_float() would be false for every field.

Example 1: which values are floats?

The loop below prints a verdict for several kinds of values. Notice that only the literals written as floats qualify.

Example
<?php
$samples = [
    'decimal literal' => 27.25,
    'integer literal' => 23,
    'numeric string' => '3.14',
    'scientific notation' => 1e3,
    'boolean' => true,
    'null' => null,
];
foreach ($samples as $label => $value) {
    echo $label, ': ', is_float($value) ? 'float' : 'not float', "\n";
}
Output
decimal literal: float
integer literal: not float
numeric string: not float
scientific notation: float
boolean: not float
null: not float

Scientific notation such as 1e3 produces a float even though its value is a whole number.

Example 2: types produced by calculations

The type of an expression's result depends on the operands and the operator, not just on the numeric value.

Example
<?php
$results = [
    'int plus int' => 2 + 3,
    'int plus float' => 2 + 3.0,
    'exact division' => 6 / 3,
    'inexact division' => 7 / 2,
    'intdiv' => intdiv(7, 2),
    'sqrt' => sqrt(16),
    'round' => round(5),
];
$report = [];
foreach ($results as $label => $value) {
    $report[$label] = is_float($value);
}
echo json_encode($report, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"int plus int":false,"int plus float":true,"exact division":false,"inexact division":true,"intdiv":false,"sqrt":true,"round":true}

Dividing two integers with / gives an integer only when the division is exact, otherwise a float. Functions such as sqrt() and round() return floats, even when the result is a whole number.

Example 3: special float values

NAN and INF are floats too. A helper can combine is_float() with related checks to describe a value.

Example
<?php
function describeNumber(mixed $value): string
{
    if (is_float($value)) {
        if (is_nan($value)) {
            return 'float NAN';
        }
        return is_infinite($value) ? 'float infinite' : 'finite float';
    }
    return is_numeric($value) ? 'numeric but not float' : 'not numeric';
}

foreach ([NAN, INF, 0.1 + 0.2, '1.5', 10, 'abc'] as $value) {
    echo describeNumber($value), "\n";
}
Output
float NAN
float infinite
finite float
numeric but not float
numeric but not float
not numeric

Because NAN and INF pass is_float(), a positive result does not guarantee a usable, finite number. Add is_finite() when that matters.

Edge cases

  • A numeric string such as '3.14' is a string, so is_float('3.14') is false. Cast with (float) or use floatval() first if you want a float.
  • is_float(-0.0) is true; negative zero is still a float.
  • An integer passed to a parameter declared as float is converted to a float on the way in, so is_float() inside that function sees true even though the caller wrote an integer.
  • Very large integer literals that exceed the platform integer range are parsed as floats, so the type depends on the magnitude.
  • Floats are approximate. is_float(0.1 + 0.2) is true, but the sum is not exactly 0.3, so compare with a tolerance rather than ==.

Common mistakes

  1. Validating form or query-string input with is_float(). Such values are strings. Use is_numeric() or filter_var() with a float filter, then convert.
  2. Assuming whole-number results are integers. round(5) and sqrt(16) give floats, so is_int() on them is false.
  3. Expecting is_float(10) to be true because 10 == 10.0. Loose equality ignores the type; is_float() does not.
  4. Treating true as a pass for a numeric check. is_float(true) is false, just as it is for null and arrays.
  5. Forgetting NAN and INF. They are floats, but arithmetic with them rarely behaves as expected.
  • is_int() tests for the integer type.
  • is_numeric() accepts numbers and numeric strings.
  • is_string(), is_bool(), is_array() and is_object() test the other types.
  • floatval() and the (float) cast convert a value to float.
  • is_nan(), is_infinite() and is_finite() inspect special float values.

Recap

is_float(mixed $value): bool returns true only when the value's type is float. It never throws, it ignores numeric strings and integers, and it still returns true for NAN and INF. Reach for is_numeric() when validating text, and combine is_float() with is_finite() when you need a real, finite number.

Tested examples

Which values are floats?
<?php
$samples = [
    'decimal literal' => 27.25,
    'integer literal' => 23,
    'numeric string' => '3.14',
    'scientific notation' => 1e3,
    'boolean' => true,
    'null' => null,
];
foreach ($samples as $label => $value) {
    echo $label, ': ', is_float($value) ? 'float' : 'not float', "\n";
}
Output
decimal literal: float
integer literal: not float
numeric string: not float
scientific notation: float
boolean: not float
null: not float
Types produced by calculations
<?php
$results = [
    'int plus int' => 2 + 3,
    'int plus float' => 2 + 3.0,
    'exact division' => 6 / 3,
    'inexact division' => 7 / 2,
    'intdiv' => intdiv(7, 2),
    'sqrt' => sqrt(16),
    'round' => round(5),
];
$report = [];
foreach ($results as $label => $value) {
    $report[$label] = is_float($value);
}
echo json_encode($report, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"int plus int":false,"int plus float":true,"exact division":false,"inexact division":true,"intdiv":false,"sqrt":true,"round":true}
Special float values
<?php
function describeNumber(mixed $value): string
{
    if (is_float($value)) {
        if (is_nan($value)) {
            return 'float NAN';
        }
        return is_infinite($value) ? 'float infinite' : 'finite float';
    }
    return is_numeric($value) ? 'numeric but not float' : 'not numeric';
}

foreach ([NAN, INF, 0.1 + 0.2, '1.5', 10, 'abc'] as $value) {
    echo describeNumber($value), "\n";
}
Output
float NAN
float infinite
finite float
numeric but not float
numeric but not float
not numeric