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
<lang ruby>class String
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}}
<lang ruby>module BaseConvert
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 dec2base(26, 16) # => "1a"
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}}==