PHP Base n Representation

Chapter 16 7 mins

Learning outcomes:

  1. Different number systems
  2. Binary (0b), octal (0o) and hexadecimal (0x) literals in PHP
  3. Conversion from decimal to binary, octal and hexadecimal
  4. Conversion from binary, octal and hexadecimal to decimal

Different number systems

The numbers that we use in our everyday calculations are based on the decimal number system, also known as the denary number system. In this system, the number 10 is used as the base. That is, each digit represents a power of 10.

Computers, however, use another system for their internal electronics. That is...you guessed it...the binary number system.

In binary, the base used is 2. Each digit can either be a ::0:: or a ::1:: and represents a power of 2. For instance, the (decimal) number ::57200:: would be written as ::1101111101110000:: in binary.

Following from the fact that binary numbers can soon become long and difficult to work with, there are two other systems used in computing: octal with a base of 8 and hexadecimal with a base of 16.

In octal, the acceptable range of each digit is ::0 - 7::, whereas in hexadecimal it's ::0 - 9:: and ::\text{a} - \text{f}::. The letters are used because there is otherwise no way to represent numbers 10 onwards in the hexadecimal system using a single digit.

The same number ::57200:: would therefore be represented as ::157560:: in octal and as ::\text{df}70:: in hexadecimal.

In mathematics, when working with different number systems, we usually we surround a given number by parentheses followed by a subscript referring to the base of the number. For instance, ::57200:: could also be expressed as ::(57200)_{10}:: (decimal), ::(1101111101110000)_{2}:: (binary), ::(157560)_{8}:: (octal) and ::(\text{df}70)_{16}:: (hexadecimal).

As a programmer you should be aware of all these common number systems used throughout computing. In the next section, we discuss how to denote binary, octal and hexadecimal numbers in PHP that ultimately resolve down to a decimal value.

Binary, octal and hexadecimal literals

It's quite standard these days for a programming language to enable notation of integers in the following three number systems: binary, octal and hexadecimal.

PHP is by no means any exception — it also enables literal notation in all three of these systems.

Here's how to express an integer in either of these systems:

  1. For binary, we prefix the integer with 0b.
  2. For octal, we prefix the integer with 0o.
  3. For hexadecimal, we prefix the integer with 0x.

For instance, the literal 0b1111 represents the binary number ::(1111)_2:: which is equal to ::15::. Similarly, the literal 0xff represents the hexadecimal number ::(\text{ff})_{16}:: which is equal to ::255::.

Why is the 0 required in the prefix?

The 0 is simply required to prevent ambiguity in the fact that whether a given source code value is a constant or a number.

For example, consider the binary number b101 supposing that there was no requirement of 0 in the prefix.

So what is this value b101? Is it the binary number ::(101)_2:: or the constant b101?

With the 0 added, this ambiguity could be removed. The constant is therefore represented as b101 while the number ::(101)_2:: is be represented as 0b101.

Simple.

Let's consider an example.

Suppose we have the integer ::30::. In binary, it's denoted as ::(11110)_2::, in octal as ::(36)_8::, and in hexadecimal as ::(1\text{e})_{16}::. In the code below, we represent this very number in all these four bases:

<?php

$dec_num = 30;
echo $dec_num, "\n";

$bin_num = 0b11110;
echo $bin_num, "\n";

$oct_num = 0o36;
echo $oct_num, "\n";

$hex_num = 0x1e;
echo $hex_num, "\n";
30 30 30 30

See how the final number stored in all of the given variables is 30. That's because these literals are just syntactic sugars for representing a given number in decimal notation — they are resolved back to the decimal system by PHP.

Moving on, if we use a character in a binary, octal or hexadecimal literal that's outside the range of acceptable characters for that very number system, PHP throws an error.

The code below illustrates this for a binary number:

<?php

// Binary number can't have the digit 2.
$num = 0b012;
PHP Parse error: syntax error, unexpected integer "2" in <path> on line 4

Decimal to binary, octal and hexadecimal

One of the most common questions asked while learning about numbers in any language is how to convert a decimal number into the binary, octal and hexadecimal number systems.

Fortunately, it's very easy in PHP.

As the names suggest, the functions decbin(), decoct() and dechex() convert a given decimal integer into a binary, octal and hexadecimal number, respectively.

Each of the functions takes one argument which is the decimal integer to convert and then returns back a string containing the integer as represented in the respective number system.

The reason why they return a string is because an integer in PHP can only be denoted in the decimal number system, so to accomodate another number system, the function has to put the converted integer inside a string.

Shown below is an example:

<?php

$num = 30;

// Convert to binary.
echo decbin($num), "\n";

// Convert to octal.
echo decoct($num), "\n";

// Convert to hexadecimal
echo dechex($num), "\n";
11110 36 1e

We have the number 30 which we convert to binary, octal and hexadecimal representations.

Time to test your understanding.

What does the following code output?

<?php

var_dump(decbin(0b1010));
  • int(10)
  • int(0b1010)
  • string(4) "1010"
0b1010 is a binary integer literal and therefore converting it to a binary string would trivially give '1010'. Hence, the correct output is (C).

Binary, octal and hexadecimal strings

Let's suppose we have the binary number ::(10111)_2:: and we want to convert it to decimal in PHP.

Now since we have the binary number available to us beforehand, we could easily write it down as a binary literal using the 0b prefix. This would give us the corresponding decimal integer.

In the code below we do this:

<?php

$num = 0b10111;

echo $num;
23

Great.

However, now imagine that we have a string containing the binary number within our code and want to convert it to a decimal integer, as follows:

<?php

// How to convert this into an integer?
$bin_str = '10111';

Now what?

We can't use a binary literal since the string is already there in the code. Moreover, in this case, we can see the string expressed as a string literal, however in real code the string might be obtained from another program and therefore we might not necessarily know it.

The good news is that the solution is once again very simple — just use the function bindec().

The functions bindec(), octdec() and hexdec() take a string argument and convert it into a decimal integer.

The return value of all these functions is an integer.

Let's consider the same example as before.

<?php

$bin_str = '10111';

var_dump(bindec($bin_str));
int(23)

As can be seen, the integer 23 is returned by bindec($bin_str).

The functions octdec() and hexdec() can be used in exactly the same way.