Non-decimal radices/Convert: Difference between revisions
Content added Content deleted
(correct header added) |
(→{{header|Ruby}}: Since Ruby 1.9.3, Integer takes a second argument (base) and is strict (errors fast).) |
||
Line 1,769: | Line 1,769: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
This converts strings from any base to any base up to base 36. |
|||
<lang ruby>s = 26.to_s(16) # returns the string 1a |
|||
⚫ | |||
i = '1a'.to_i(16) # returns the integer 26</lang> |
|||
def convert_base(from, to) |
|||
Caution: <tt>to_i</tt> simply stops when it reaches an invalid character; it does not raise any exceptions. So sometimes it may appear to parse something and get a result, but it is only based on part of the input string: |
|||
Integer(self, from).to_s(to) |
|||
<lang ruby>"59".to_i(7) # returns 5, but this is probably not what you wanted</lang> |
|||
# self.to_i(from).to_s(to) #if you don't want exceptions |
|||
For a general base parsing that raises an exception for invalid characters: |
|||
{{trans|Tcl}} |
|||
⚫ | |||
DIGITS = [*"0".."9", *"a".."z"] |
|||
def baseconvert(str, basefrom, baseto) |
|||
dec2base(base2dec(str, basefrom), baseto) |
|||
end |
|||
def base2dec(str, base) |
|||
raise ArgumentError, "base is invalid" unless base.between?(2, DIGITS.length) |
|||
str.to_s.downcase.each_char.inject(0) do |res, c| |
|||
idx = DIGITS[0,base].index(c) |
|||
idx.nil? and raise ArgumentError, "invalid base-#{base} digit: #{c}" |
|||
res = res * base + idx |
|||
end |
|||
end |
|||
def dec2base(n, base) |
|||
return "0" if n == 0 |
|||
raise ArgumentError, "base is invalid" unless base.between?(2, DIGITS.length) |
|||
res = [] |
|||
while n > 0 |
|||
n, r = n.divmod(base) |
|||
res.unshift(DIGITS[r]) |
|||
end |
|||
res.join |
|||
end |
end |
||
end |
end |
||
# first three taken from TCL |
|||
include BaseConvert |
|||
p |
p "12345".convert_base(10, 23) # "107h" |
||
p "107h".convert_base(23, 7) # "50664" |
|||
p base2dec("1a", 16) # => 26 |
|||
p "50664".convert_base(7, 10) # "12345" |
|||
p baseconvert("107h", 23, 7) # => "50664"</lang> |
|||
p "ff".convert_base(15, 10) # => ArgumentError</lang> |
|||
=={{header|Run BASIC}}== |
=={{header|Run BASIC}}== |