--- name: oct signature: 'oct EXPR' since: 5.0 status: documented categories: ["SCALARs and strings", "Numeric functions"] --- ```{index} single: oct; Perl built-in ``` *[SCALARs and strings](../perlfunc-by-category) · [Numeric functions](../perlfunc-by-category)* # 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 [`$_`](../perlvar). 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 ```perl 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 `>= 0` — `oct` does not parse a leading sign and does not return floating-point values. An empty string, a string with no recognised digits, or [`undef`](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: ```perl 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`](chmod) expects the number: ```perl my $mode = "0755"; chmod oct($mode), "script.sh"; # chmod 0755 ``` ```perl 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: ```perl 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: ```perl my $n = $val =~ /^0/ ? oct($val) : $val; ``` Default-argument form operates on [`$_`](../perlvar), handy inside [`map`](map): ```perl my @perms = map { oct } @mode_strings; ``` Round-trip with [`sprintf`](sprintf) to go the other direction: ```perl 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`](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`](hex) — forces base 16 regardless of prefix; use it when the input is *always* hex and you do not want `oct`'s autodetection - [`int`](int) — truncate a numeric value toward zero; unrelated to radix parsing but often reached for by accident - [`chmod`](chmod) — the canonical consumer of `oct`; takes a numeric mode, so string-form modes must go through `oct` first - [`sprintf`](sprintf) — the inverse direction: format `%o`, `%x`, `%b` turn an integer into its octal/hex/binary textual form