Non-decimal radices/Input: Difference between revisions

From Rosetta Code
Content added Content deleted
(Made a task to show off number parsing)
 
(→‎{{header|Tcl}}: + scanbase for bases up to 36)
Line 25: Line 25:
This produces this output:
This produces this output:
<pre>0123459->123459 abcf123->180154659 7651->4009 101011001->345</pre>
<pre>0123459->123459 abcf123->180154659 7651->4009 101011001->345</pre>

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 $digits $char]
if {$value < 0} {error "bad digit $char"}
set res [expr {$res*$base + $value}]
}
return $res
}</lang>
Example:
<pre>% scanbase 255 19
822</pre>

Revision as of 09:27, 9 June 2009

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

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.)

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.

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 $digits $char]
     if {$value < 0} {error "bad digit $char"}
     set res [expr {$res*$base + $value}]
  }
  return $res

}</lang> Example:

% scanbase 255 19
822