It is common to have a string containing a number written in some format, with the most common ones being decimal, hexadecimal, octal and binary. Such strings are found in many places (user interfaces, configuration files, XML data, network protocols, etc.)

Task
Non-decimal radices/Input
You are encouraged to solve this task according to the task description, using any language you may know.

This task requires parsing of such a string (which may be assumed to contain nothing else) using the language's built-in facilities if possible. Parsing of decimal strings is required, parsing of other formats is optional but should be shown (i.e., if the language can parse in base-19 then that should be illustrated).

The solutions may assume that the base of the number in the string is known. In particular, if your language has a facility to guess the base of a number by looking at a prefix (e.g. "0x" for hexadecimal) or other distinguishing syntax as it parses it, please show that.

The reverse operation is in task Common number base formatting

For general number base conversion, see Number base conversion.

AutoHotkey

There is no built in support for generic base parsing.
Please see Number_base_conversion

ALGOL 68

Translation of: C
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny

<lang algol68>main: (

 FILE fbuf; STRING sbuf; 
 OP FBUF = (STRING in sbuf)REF FILE: (
   sbuf := in sbuf; 
   associate(fbuf, sbuf);
   fbuf
 );
 BITS num;

 getf(FBUF("0123459"), ($10r7d$, num));
 printf(($gl$, ABS num)); # prints 123459 #

 getf(FBUF("abcf123"), ($16r7d$, num));
 printf(($gl$, ABS num)); # prints 180154659 #

 getf(FBUF("7651"), ($8r4d$, num));
 printf(($gl$, ABS num)); # prints 4009 #

 getf(FBUF("1010011010"), ($2r10d$, num));
 printf(($gl$, ABS num)) # prints 666 #

)</lang> Output:

    +123459
 +180154659
      +4009
       +666

C

In addition to strtol() described in the Number base conversion task, you could also use the scanf family of functions to parse un-prefixed hexadecimal, decimal, and octal numbers: <lang c>#include <stdio.h>

int main() {

 int num;
 sscanf("0123459", "%d", &num);
 printf("%d\n", num); /* prints 123459 */
 sscanf("abcf123", "%x", &num);
 printf("%d\n", num); /* prints 180154659 */
 sscanf("7651", "%o", &num);
 printf("%d\n", num); /* prints 4009 */
 /* binary not supported */
 return 0;

}</lang>

The strtol() function can also parse prefixed hexadecimal, octal, and decimal strings based on the prefix, when passed a base of 0: <lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <assert.h>

int main() {

 int num;
 char *endptr;
 num = strtol("123459", &endptr, 0);
 assert(*endptr == '\0');
 printf("%d\n", num); /* prints 123459 */
 num = strtol("0xabcf123", &endptr, 0);
 assert(*endptr == '\0');
 printf("%d\n", num); /* prints 180154659 */
 num = strtol("07651", &endptr, 0);
 assert(*endptr == '\0');
 printf("%d\n", num); /* prints 4009 */
 /* binary not supported */
 return 0;

}</lang>

C++

<lang cpp>#include <iostream>

  1. include <sstream>

int main() {

 int num;
 std::istringstream("0123459") >> num;
 std::cout << num << std::endl; // prints 123459
 std::istringstream("0123459") >> std::dec >> num;
 std::cout << num << std::endl; // prints 123459
 std::istringstream("abcf123") >> std::hex >> num;
 std::cout << num << std::endl; // prints 180154659
 std::istringstream("7651") >> std::oct >> num;
 std::cout << num << std::endl; // prints 4009
 // binary not supported
 return 0;

}</lang>

Common Lisp

<lang lisp>(parse-integer "abc" :radix 20 :junk-allowed t) ; => 4232</lang>

If :radix is omitted, it defaults to 10. If :junk-allowed is omitted, it defaults to nil, causing #'parse-integer to signal an error of type parse-error rather than just returning nil whenever the input string isn't a numeral possibly surrounded by whitespace.

E

<lang e>? __makeInt("200", 16)

  1. value: 512

? __makeInt("200", 10)

  1. value: 200</lang>

Factor

Bases from 2 to 16 are supported through the generic base> word (see online docs [1]) but 4 functions are defined for the most used cases:

   ( scratchpad ) "ff" hex> . ! base 16
   255
   ( scratchpad ) "777" oct> . ! base 8
   511
   ( scratchpad ) "1111" bin> . ! base 2
   15
   ( scratchpad ) "99" string>number . ! base 10
   99

Note that these words are very simple : for example, here's oct> : <lang factor>IN: math.parser

oct> ( str -- n/f ) 8 base> ; inline</lang>

Also, fractions are handled transparently :

   ( scratchpad ) "1+F/2" hex> .
   8+1/2

Hex floats are supported, anything else is taken as base 10 :

   ( scratchpad ) "ff.f" hex> .
   255.9375
   ( scratchpad ) "11.1101" bin> .
   11.1101

Forth

Arbitrary base 2-36 parsing is supported by the same mechanism as decimal parsing: set the user variable BASE to the desired base, then scan the number. There are two convenience words for setting the base to DECIMAL or HEX. <lang forth>: parse# ( str len -- u true | false )

  0. 2SWAP DUP >R >NUMBER NIP NIP 
  R> <> DUP 0= IF NIP THEN ;
base# ( str len base -- u true | false )
 BASE @ >R  BASE !  parse#  R> BASE ! ;</lang>

Haskell

Haskell's read can parse strings with the same prefix used for literals in Haskell (0x or 0X for hex, 0o or 0O for octal): <lang haskell>Prelude> read "123459" :: Integer 123459 Prelude> read "0xabcf123" :: Integer 180154659 Prelude> read "0o7651" :: Integer 4009</lang>

J

This will satisfy the requirements:

<lang j>baseN=: 0&".@,&": 'b' , ]

  16 baseN 'abcf123'

180154659

  8 baseN '7651'

4009

  10 baseN '123459'

123459</lang>

Java

Works with: Java version 1.5+

You must know the base that the String is in before you scan it. Create a Scanner in the usual way, but then set its radix to that base (obviously, the default is 10): <lang java5>Scanner sc = new Scanner(System.in); //or any other InputStream or String sc.useRadix(base); //any number from Character.MIN_RADIX (2) to CHARACTER.MAX_RADIX (36) sc.nextInt(); //read in a value</lang> Later you can call sc.reset() or sc.useRadix(10) to undo this change.

Another option using the Integer class: <lang java>int number = Integer.parseInt(stringNum, base);</lang> The base here has the same restrictions as the Scanner example. A similar method is available in the Long class. Use no second argument for base 10.

If you have a prefixed string ("0x", "0X", or "#" for hex; "0" for octal; otherwise decimal), you can use the .decode() utility method to parse the number based on the base indicated by the prefix (note: this returns an Integer object, not a primitive int): <lang java>Integer.decode("0xabcf123"); // hex Integer.decode("07651"); // octal Integer.decode("123459"); // decimal</lang> Long, Short, and Byte also have a .decode() method, to decode to the appropriate number object type.

JavaScript

The parseInt(string,radix) core function is the reverse of the number.toString(radix) method. The following is taken from Mozilla's JavaScript 1.5 reference.

The following examples all return 15:

<lang javascript>parseInt(" 0xF", 16); parseInt(" F", 16); parseInt("17", 8); parseInt(021, 8); parseInt("015", 10); parseInt(15.99, 10); parseInt("FXX123", 16); parseInt("1111", 2); parseInt("15*3", 10); parseInt("15e2", 10); parseInt("15px", 10); parseInt("12", 13);</lang>

The following examples all return NaN:

<lang javascript>parseInt("Hello", 8); // Not a number at all parseInt("546", 2); // Digits are not valid for binary representations</lang>

The following examples all return -15:

<lang javascript>parseInt("-F", 16); parseInt("-0F", 16); parseInt("-0XF", 16); parseInt(-10, 16); parseInt(-15.1, 10) parseInt(" -17", 8); parseInt(" -15", 10); parseInt("-1111", 2); parseInt("-15e1", 10); parseInt("-12", 13);</lang>

The following example returns 224:

<lang javascript>parseInt("0e0", 16);</lang>

Although it is optional, most implementations interpret a numeric string beginning with a leading '0' as octal. The following may have an octal result.

<lang javascript>parseInt("0e0"); // 0

parseInt("08"); // 0, '8' is not an octal digit.</lang>

OCaml

The int_of_string function can parse hexadecimal, octal, and binary numbers that have the same prefix that is used to specify OCaml constants ("0x", "0o", and "0b", respectively): <lang ocaml># int_of_string "123459";; - : int = 123459

  1. int_of_string "0xabcf123";;

- : int = 180154659

  1. int_of_string "0o7651";;

- : int = 4009

  1. int_of_string "0b101011001";;

- : int = 345</lang> The Int32.of_string, Int64.of_string, and Nativeint.of_string functions also can understand the above prefixes when parsing into their appropriate types.

Unfortunately, the Big_int.big_int_of_string function does not understand these prefixes.

You could also use the Scanf module to parse un-prefixed hexadecimal, decimal, and octal numbers (binary not supported): <lang ocaml># Scanf.sscanf "123459" "%d" (fun x -> x);; - : int = 123459

  1. Scanf.sscanf "abcf123" "%x" (fun x -> x);;

- : int = 180154659

  1. Scanf.sscanf "7651" "%o" (fun x -> x);;

- : int = 4009</lang>

Oz

String.toInt understands the usual prefixes. If a string cannot be parsed, an exception will be thrown. <lang oz>{String.toInt "42"}  %% decimal = {String.toInt "0x2a"}  %% hexadecimal = {String.toInt "052"}  %% octal = {String.toInt "0b101010"} %% binary</lang>

Perl

The hex() function parses hexadecimal strings. The oct() function parses octal strings, as well as hexadecimal, octal, or binary strings with the appropriate prefix ("0x", "0", and "0b", respectively). There is no need to parse decimal strings because in Perl decimal strings and numbers are interchangeable. <lang perl>my $dec = "0123459"; my $hex_noprefix = "abcf123"; my $hex_withprefix = "0xabcf123"; my $oct_noprefix = "7651"; my $oct_withprefix = "07651"; my $bin_withprefix = "0b101011001";

print 0 + $dec, "\n"; # => 123459 print hex($hex_noprefix), "\n"; # => 180154659 print hex($hex_withprefix), "\n"; # => 180154659 print oct($hex_withprefix), "\n"; # => 180154659 print oct($oct_noprefix), "\n"; # => 4009 print oct($oct_withprefix), "\n"; # => 4009 print oct($bin_withprefix), "\n"; # => 345

  1. nothing for binary without prefix</lang>

PHP

The hexdec(), octdec(), bindec() function parses hexadecimal, octal, and binary strings, respectively. They skip any invalid characters, so a prefix will be ignored. There is no need to parse decimal strings because in Perl decimal strings and numbers are interchangeable. <lang php><?php echo 0 + "0123459", "\n"; // prints 123459 echo hexdec("abcf123"), "\n"; // prints 180154659 echo octdec("7651"), "\n"; // prints 4009 echo bindec("101011001"), "\n"; // prints 345 ?></lang>

An undocumented feature of intval() is that it can parse prefixed strings when given the base 0: <lang php><?php echo intval("123459", 0), "\n"; // prints 123459 echo intval("0xabcf123", 0), "\n"; // prints 180154659 echo intval("07651", 0), "\n"; // prints 4009 ?></lang>

In addition, for hexadecimals, if you have a "0x"-prefixed string, you can just use it in a numeric operation, and it gets converted to the number automatically: <lang php><?php echo 0 + '0xabcf123', "\n"; // prints 180154659

  1. This does not work for octals, however:

echo 0 + '07651', "\n"; // prints 7651 ?></lang>

PL/I

<lang PL/I> get edit (N) (A(7)); /* decimal input of 7 columns */ put skip list (N);

declare BS bit (32); get edit (BS) (B(32)); /* Binary input of 32 binary digits. */ put skip edit (BS) (B); </lang>

PicoLisp

<lang PicoLisp>(de parseNumber (S Base)

  (let N 0
     (for C (chop S)
        (when (> (setq C (- (char C) `(char "0"))) 9)
           (dec 'C 39) )
        (setq N (+ C (* N Base))) )
     N ) )

(println (parseNumber "91g5dcg2h6da7260a9f3c4a" 19))</lang> Output:

123456789012345678901234567890

PureBasic

<lang PureBasic> ;Val() parses integer strings

 ; decimal numbers have no prefix, hexadecimal needs a prefix of '$', binary needs a prefix of '%'
 Val("1024102410241024")      ; => 1024102410241024
 Val("$10FFFFFFFF")           ; => 73014444031
 Val("%1000")                 ; => 8</lang>

Python

The int function will interpret strings as numbers expressed to some base: <lang python>>>> text = '100' >>> for base in range(2,21):

   print ("String '%s' in base %i is  %i in base 10" 
          % (text, base, int(text, base)))


String '100' in base 2 is 4 in base 10 String '100' in base 3 is 9 in base 10 String '100' in base 4 is 16 in base 10 String '100' in base 5 is 25 in base 10 String '100' in base 6 is 36 in base 10 String '100' in base 7 is 49 in base 10 String '100' in base 8 is 64 in base 10 String '100' in base 9 is 81 in base 10 String '100' in base 10 is 100 in base 10 String '100' in base 11 is 121 in base 10 String '100' in base 12 is 144 in base 10 String '100' in base 13 is 169 in base 10 String '100' in base 14 is 196 in base 10 String '100' in base 15 is 225 in base 10 String '100' in base 16 is 256 in base 10 String '100' in base 17 is 289 in base 10 String '100' in base 18 is 324 in base 10 String '100' in base 19 is 361 in base 10 String '100' in base 20 is 400 in base 10</lang>

In addition, if you give a base of 0, it will try to figure out the base from the prefix, with the same syntax as a numeric literal in Python:

Python 3.x and 2.6:

>>> int("123459", 0)
123459
>>> int("0xabcf123", 0)
180154659
>>> int("0o7651", 0)
4009
>>> int("0b101011001", 0)
345

Python 2.x:

>>> int("123459", 0)
123459
>>> int("0xabcf123", 0)
180154659
>>> int("07651", 0)
4009

Python 2.6 supports both the above formats, because it supports both types of literals.

R

<lang R># parse a string to decimal as.numeric("20") # 20

  1. parse a hex-string to decimal

as.numeric("0x20") # 32

  1. parse a string to hexadecimal

as.hexmode(as.numeric("32")) # "20"

  1. parse a string to octal

as.octmode(as.numeric("20")) # "24"</lang>

Ruby

The String class has methods to coerce a string into another form: <lang ruby>dec1 = "0123459" hex2 = "abcf123" oct3 = "7651" bin4 = "101011001"

dec1.to_i # => 123459 hex2.hex # => 180154659 oct3.oct # => 4009

  1. nothing for binary</lang>

The Integer class can parse a string, provided the string has the right prefix: <lang ruby>Integer(dec1) # => ArgumentError: invalid value for Integer: "0123459" Integer(dec1.sub(/^0+/,"")) # => 123459 Integer("0x" + hex2) # => 180154659 Integer("0" + oct3) # => 4009 Integer("0b" + bin4) # => 345</lang>

So can the .to_i(0) method, which never raises an exception: <lang ruby>dec1.to_i(0) # => 5349 (which is 12345 in octal, the 9 is discarded) dec1.sub(/^0+/,"").to_i(0) # => 123459 ("0x" + hex2).to_i(0) # => 180154659 ("0" + oct3).to_i(0) # => 4009 ("0b" + bin4).to_i(0) # => 345</lang>

And then there's the poorly documented Scanf module in the Ruby stdlib, that seems to wrap the matched value in an array: <lang ruby>require 'scanf' dec1.scanf("%d") # => [123459] hex2.scanf("%x") # => [180154659] oct3.scanf("%o") # => [4009]

  1. no scanf specifier for binary numbers.</lang>

Scheme

<lang scheme>> (string->number "abcf123" 16) ; hex 180154659 > (string->number "123459" 10) ; decimal, the "10" is optional 123459 > (string->number "7651" 8) ; octal 4009 > (string->number "101011001" 2) ; binary 345</lang>

Standard ML

<lang sml>- Int.fromString "0123459"; val it = SOME 123459 : int option - StringCvt.scanString (Int.scan StringCvt.HEX) "0xabcf123"; val it = SOME 180154659 : int option - StringCvt.scanString (Int.scan StringCvt.HEX) "abcf123"; val it = SOME 180154659 : int option - StringCvt.scanString (Int.scan StringCvt.OCT) "7651"; val it = SOME 4009 : int option - StringCvt.scanString (Int.scan StringCvt.BIN) "101011001"; val it = SOME 345 : int option</lang>

Tcl

<lang tcl>package require Tcl 8.6; # For easy scanning of binary

  1. The strings to parse

set dec1 "0123459" set hex2 "abcf123" set oct3 "7651" set bin4 "101011001"

  1. Parse the numbers

scan $dec1 "%d" v1 scan $hex2 "%x" v2 scan $oct3 "%o" v3 scan $bin4 "%b" v4; # Only 8.6-specific operation; others work in all versions

  1. Print out what happened

puts "$dec1->$v1 $hex2->$v2 $oct3->$v3 $bin4->$v4"</lang> This produces this output:

0123459->123459 abcf123->180154659 7651->4009 101011001->345

For a general parser up to base 36, a little function can be written: <lang Tcl>proc scanbase {str base} {

  set res 0
  set digits {0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z}
  foreach char [split [string tolower $str] ""] {
     set value [lsearch [lrange $digits 0 [expr {$base - 1}]] $char]
     if {$value < 0} {error "bad digit $char"}
     set res [expr {$res*$base + $value}]
  }
  return $res

}</lang> Example:

% scanbase 255 19
822
% scanbase $dec1 8
bad digit 9