Mathematics7 min readExamples run on PHP 8.5.10

bindec()

Learn how PHP 8.4 bindec() turns a string of binary digits into an int or float, including unsigned behavior, large inputs and invalid characters.

Signature

bindec(string $binary_string): int|float

Purpose

bindec() reads a string made of the characters 0 and 1 and returns the number it represents. It is the counterpart of decbin(). Use it when binary data arrives as text, for example a permission mask typed as 0101, a bit pattern read from a configuration value, or a teaching tool that shows how positional notation works.

The function treats the string as a plain positional number. The rightmost digit is worth 1, the next one 2, then 4, 8 and so on.

Signature

Parameters and defaults

binary_string is the only parameter and it has no default. It must be a string. The manual warns that passing other data types gives unexpected results, so convert values to strings yourself first. A common trap is passing the integer 101, which PHP would turn into the string "101"; that works by accident, but only because the decimal digits happen to look binary. Keep the input as a string from the start, especially when it has leading zeros.

Leading zeros are harmless: '000110011' and '110011' give the same result.

Return value and failure cases

The return type is int|float. If the value fits in PHP's native integer, you get an int. If it is too large for the platform's integer type, you get a float instead, and a float can lose precision for very large values.

bindec() never throws an exception for bad input. Instead:

  • An empty string gives 0.
  • Any character other than 0 or 1 is ignored when the number is computed. Since PHP 7.4.0, supplying such characters also raises a deprecation notice, but the result is still calculated as if those characters were not there.

Because nothing fails loudly, validate the input yourself if it comes from users, for example with a check that the string matches ^[01]+$ before converting.

Example 1: basic conversion

This example converts a few strings, including one with leading zeros and an empty string.

Example
<?php
$values = [
    bindec('110011'),
    bindec('000110011'),
    bindec('111'),
    bindec(''),
];
echo json_encode($values);
Output
[51,51,7,0]

The first two entries are both 51, the third is 7, and the empty string yields 0.

Example 2: reading permission bits

Binary strings are a readable way to describe flags. After converting, use bitwise operators to test each bit.

Example
<?php
$flags = bindec('0101');
$result = [
    'value' => $flags,
    'read' => ($flags & 4) !== 0,
    'write' => ($flags & 2) !== 0,
    'exec' => ($flags & 1) !== 0,
];
echo json_encode($result);
Output
{"value":5,"read":true,"write":false,"exec":true}

The string 0101 equals 5, which has the 4 bit and the 1 bit set but not the 2 bit.

Example 3: int versus float

Small results are integers. A string with 64 ones is larger than any signed integer PHP can store, so the result becomes a float.

Example
<?php
$small = bindec(str_repeat('1', 31));
$big = bindec(str_repeat('1', 64));
echo json_encode([$small, is_int($small), is_float($big)]);
Output
[2147483647,true,true]

The 31 ones give 2147483647, an int, while the 64 ones give a float.

Edge cases

Unsigned interpretation. bindec() does not treat the leftmost bit as a sign bit. A string of 64 ones is not -1; it is read as a huge positive number, which cannot be represented exactly as a float. Likewise, a 1 followed by 63 zeros on a 64-bit build is one more than PHP_INT_MAX, so the result is a float. If you need two's complement behavior, you must apply it yourself.

Float precision. Once the result becomes a float, only about 15 to 17 significant decimal digits are reliable. Do not use such values for exact comparisons or further bit operations.

Platform size. The point at which the result switches from int to float depends on the size of PHP's integer type on the platform. Write code that checks is_int() or is_float() instead of assuming one threshold.

Whitespace and signs. Spaces, minus signs, decimal points and similar characters are invalid and are skipped, with a deprecation notice in modern PHP. The string '-101' therefore becomes 5, not -5.

Common mistakes

  1. Passing an integer literal. Writing bindec(1010) relies on implicit conversion and loses any leading zeros. Pass '1010'.
  2. Expecting errors on bad input. Characters like 2 or a do not stop the script. They are dropped, so '1021' is computed as '101', which is 5.
  3. Expecting negative results. The function only returns non-negative numbers.
  4. Ignoring the float case. Code that assumes an int return may break when long strings are supplied. Limit the input length if you need exact integers.
  5. Confusing it with the opposite direction. To go from a number to a binary string, use decbin().
  • decbin() converts a decimal number to a binary string.
  • octdec() converts an octal string to decimal.
  • hexdec() converts a hexadecimal string to decimal.
  • base_convert() converts between arbitrary bases from 2 to 36, always returning a string.

Recap

bindec() converts a string of binary digits into a decimal int, or a float when the value is too large. It reads the input as unsigned, ignores invalid characters (with a deprecation notice since PHP 7.4.0) and returns 0 for an empty string. Pass strings, validate untrusted input first, and watch for float precision loss with long bit patterns.

Tested examples

Basic conversion of binary strings
<?php
$values = [
    bindec('110011'),
    bindec('000110011'),
    bindec('111'),
    bindec(''),
];
echo json_encode($values);
Output
[51,51,7,0]
Reading permission bits
<?php
$flags = bindec('0101');
$result = [
    'value' => $flags,
    'read' => ($flags & 4) !== 0,
    'write' => ($flags & 2) !== 0,
    'exec' => ($flags & 1) !== 0,
];
echo json_encode($result);
Output
{"value":5,"read":true,"write":false,"exec":true}
Integer versus float results
<?php
$small = bindec(str_repeat('1', 31));
$big = bindec(str_repeat('1', 64));
echo json_encode([$small, is_int($small), is_float($big)]);
Output
[2147483647,true,true]