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:
- For binary, we prefix the integer with
0b
. - For octal, we prefix the integer with
0o
. - 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";
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;
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.
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";
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;
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()
.
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));
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.