# Recipe 2.15 Converting Binary, Octal, and Hexadecimal Numbers

#### 2.15.1 Problem

You want to convert a string (e.g., "0b10110", "0x55", or "0755") containing a binary, octal, or hexadecimal number to the correct number.

Perl understands numbers specified in binary (base-2), octal (base-8), and hexadecimal (base-16) notation only when they occur as literals in your programs. If they come in as datasuch as by reading from files or environment variables, or when supplied as command-line argumentsno automatic conversion takes place.

#### 2.15.2 Solution

Use Perl's hex function if you have a hexadecimal string like "2e" or "0x2e":

`\$number = hex(\$hexadecimal);         # hexadecimal only ("2e" becomes 47)`

Use the oct function if you have a hexadecimal string like "0x2e", an octal string like "047", or a binary string like "0b101110":

```\$number = oct(\$hexadecimal);         # "0x2e" becomes 47
\$number = oct(\$octal);               # "057"  becomes 47
\$number = oct(\$binary);              # "0b101110" becomes 47```

#### 2.15.3 Discussion

The oct function converts octal numbers with or without the leading "0"; for example, "0350" or "350". Despite its name, oct does more than convert octal numbers: it also converts hexadecimal ("0x350") numbers if they have a leading "0x" and binary ("0b101010") numbers if they have a leading "0b". The hex function converts only hexadecimal numbers, with or without a leading "0x": "0x255", "3A", "ff", or "deadbeef". (Letters may be in upper- or lowercase.)

Here's an example that accepts an integer in decimal, binary, octal, or hex, and prints that integer in all four bases. It uses the oct function to convert the data from binary, octal, and hexadecimal if the input begins with a 0. It then uses printf to convert into all four bases as needed.

```print "Gimme an integer in decimal, binary, octal, or hex: ";
\$num = <STDIN>;
chomp \$num;
exit unless defined \$num;
\$num = oct(\$num) if \$num =~ /^0/; # catches 077 0b10 0x20
printf "%d %#x %#o %#b\n", (\$num) x 4;```

The # symbol between the percent and the three non-decimal bases makes printf produce output that indicates which base the integer is in. For example, if you enter the number 255, the output would be:

`255 0xff 0377 0b11111111`

But without the # sign, you would only get:

`255 ff 377 11111111`

The following code converts Unix file permissions. They're always given in octal, so we use oct instead of hex.

```print "Enter file permission in octal: ";
\$permissions = <STDIN>;
die "Exiting ...\n" unless defined \$permissions;
chomp \$permissions;
\$permissions = oct(\$permissions);   # permissions always octal
print "The decimal value is \$permissions\n";```

The "Scalar Value Constructors" section in perldata(1) and the "Numeric Literals" section of Chapter 2 of Programming Perl; the oct and hex functions in perlfunc(1) and Chapter 29 of Programming Perl

 Chapter 1. Strings
 Chapter 3. Dates and Times
 Chapter 4. Arrays
 Chapter 5. Hashes
 Chapter 6. Pattern Matching
 Chapter 7. File Access
 Chapter 8. File Contents
 Chapter 9. Directories
 Chapter 10. Subroutines
 Chapter 11. References and Records
 Chapter 12. Packages, Libraries, and Modules
 Chapter 13. Classes, Objects, and Ties
 Chapter 14. Database Access
 Chapter 15. Interactivity
 Chapter 16. Process Management and Communication
 Chapter 17. Sockets
 Chapter 18. Internet Services
 Chapter 19. CGI Programming
 Chapter 20. Web Automation
 Chapter 21. mod_perl
 Chapter 22. XML