SCALARs and strings · Numeric functions

oct#

Interpret a string as a number written in octal, hexadecimal, or binary, and return the resulting integer.

The name is misleading: oct is really a radix-prefix parser. It inspects the leading characters of EXPR and picks the base from them — 0x/x for hexadecimal, 0b/b for binary, 0o/o (or no prefix at all) for octal. If EXPR is omitted, oct works on $_. Think of it as the inverse of sprintf "%o" / "%x" / "%b" for the common case where you have the textual form and need the number.

Synopsis#

oct EXPR
oct                 # operates on $_

What you get back#

A non-negative integer. The numeric value of EXPR interpreted in whichever base its prefix selected (octal by default). The result is always >= 0oct does not parse a leading sign and does not return floating-point values.

An empty string, a string with no recognised digits, or undef returns 0.

Prefix rules#

The leading characters of EXPR (after any leading whitespace, which is silently skipped) determine the base:

Prefix

Base

Example input

Result

0x or x

16 (hex)

"0xff"

255

0b or b

2 (binary)

"0b1010"

10

0o or o

8 (octal)

"0o755"

493

(none)

8 (octal)

"755"

493

(none, leading 0)

8 (octal)

"0755"

493

The 0o/o octal prefix was added in Perl 5.33.5 to match integer literal syntax; older forms (0755 and a bare 755) have always been octal.

Underscores between digits are ignored, so values copied straight from Perl integer literals parse cleanly:

oct("0xDEAD_BEEF")      # 3735928559
oct("0b1111_0000")      # 240
oct("07_55")            # 493

Examples#

Decode a permission string typed by a user — the whole reason oct exists. The string "755" is not the number 755; it is the octal representation of the number 493. chmod expects the number:

my $mode = "0755";
chmod oct($mode), "script.sh";          # chmod 0755
my $mode = "755";                       # no leading zero — still octal
chmod oct($mode), "script.sh";          # same result

Parse hex and binary literals read from a config file or a command line:

my $mask  = oct("0xff00");              # 65280
my $flags = oct("0b1010_0101");         # 165

Handle arbitrary radix-prefixed strings — decimal, octal, hex, or binary — in one expression. This is the classic oct-as-dispatcher idiom: a leading 0 (in any of its forms) means “not decimal”, so route through oct; otherwise keep the value as-is:

my $n = $val =~ /^0/ ? oct($val) : $val;

Default-argument form operates on $_, handy inside map:

my @perms = map { oct } @mode_strings;

Round-trip with sprintf to go the other direction:

my $perm = (stat $file)[2] & 07777;
my $text = sprintf "%o", $perm;         # e.g. "644"
my $back = oct($text);                  # back to the same integer

Edge cases#

  • Empty or undef input: oct("") and oct(undef) both return 0. undef triggers an uninitialized warning under use warnings.

  • No prefix defaults to octal: oct("12") is 10, not 12. This is a frequent surprise — if your strings might be decimal, test for a leading 0 first (see the idiom above) or do not use oct at all and parse explicitly.

  • Underscores are ignored wherever they appear between digits. oct("0x_de_ad") is 57005. Leading and trailing underscores are also silently accepted.

  • Invalid characters terminate parsing: parsing stops at the first character that does not belong to the selected base; the rest of the string is discarded without a warning. oct("0x1g2") returns 1, oct("755.5") returns 493, oct("12abc") returns 10 (octal, stopped at a), oct("0b102") returns 2 (binary 10, stopped at 2).

  • Leading whitespace is skipped silently. A leading + or - is not a sign — it is a non-digit, so parsing returns 0. oct cannot produce a negative number.

  • Floating-point and exponent notation are not understood. There is no 0x1.8p3 support; the . terminates parsing.

  • Case of prefix and digits is insensitive: 0X, 0B, 0O, and hex digits a-f/A-F are all accepted.

  • Overflow: values larger than the platform integer silently promote to floating point, losing low-order precision for very large hex/binary inputs.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • hex — forces base 16 regardless of prefix; use it when the input is always hex and you do not want oct’s autodetection

  • int — truncate a numeric value toward zero; unrelated to radix parsing but often reached for by accident

  • chmod — the canonical consumer of oct; takes a numeric mode, so string-form modes must go through oct first

  • sprintf — the inverse direction: format %o, %x, %b turn an integer into its octal/hex/binary textual form