Преобразование шестнадцатеричных, десятичных, восьмеричных и ASCII?

Попытка и с базы в Ruby... код, который я выложил, кажется довольно повторяющимся. Лучше ли это?

module Converter
  def self.convert(value, from, to)
    case from
    when :hex
      case to
      when :dec
        # code to change hex to dec
      when :oct
        # code to change hex to oct
      when :bin
        # code to change hex to bin
      when :ascii
        # code to change hex to ascii
      end
    when :dec
      case to
      when :hex
        # code to change dec to hex
      when :oct
        # code to change dec to oct
      when :bin
        # code to change dec to bin
      when :ascii
        # code to change dec to ascii
      end
    when :oct
      case to
      when :hex
        # code to change oct to hex
      when :dec
        # code to change oct to dec
      when :bin
        # code to change oct to bin
      when :ascii
        # code to change oct to ascii
      end
    when :bin
      case to
      when :hex
        # code to change bin to hex
      when :dec
        # code to change bin to dec
      when :oct
        # code to change bin to oct
      when :ascii
        # code to change bin to ascii
      end
    when :ascii
      case to
      when :hex
        # code to change ascii to hex
      when :dec
        # code to change ascii to dec
      when :oct
        # code to change ascii to oct
      when :bin
        # code to change ascii to bin
      end
    end
  end
end

Ответы

Ответ 1

class String
  def convert_base(from, to)
    self.to_i(from).to_s(to)
    # works up-to base 36
  end
end

p '1010'.convert_base(2, 10) #=> "10"
p 'FF'.convert_base(16, 2)   #=> "11111111"

Ответ 2

Придумайте код для преобразования от чего угодно до десятичного и от десятичного к чему угодно, а затем объедините их. Например. для преобразования из двоичного в шестнадцатеричный, сначала преобразовать в десятичный, а затем в шестнадцатеричный. Базовое преобразование также тривиально реализуется общим способом, который может обрабатывать любую базу, учитывая набор цифр, которые он использует.

Кроме того, помните, что числовое значение в памяти на самом деле не имеет понятия базы (оно представлено как двоичное, очевидно, но в основном не имеет значения). Это просто ценность. Только после того, как вы задействуете струны, базы становятся действительно значительными. Поэтому, если ваш "десятичный" действительно означает числовое значение вместо строки цифр, лучше не называть его "десятичным".

Ответ 3

Я не согласен с использованием класса String для управления двоичными данными. Казалось бы, более целесообразно использовать Fixnum, поскольку в этом классе есть побитовые операторы. Конечно, класс String имеет String # to_s с "ENV" и изменит Integer на новую базу,   10.to_s(16) здесь мы работаем с цифрами. Но это просто ИМХО. Хороший ответ в противном случае.

Здесь мои примеры использования для Fixnum.

class Fixnum
  def convert_base(to)
    self.to_s(to).to_i
  end
end

p '1010'.to_i(2).convert_base(10) #=> 10  real numbers
p 'FF'.hex.convert_base(2)        #=> 11111111
p 72.convert_base(16)             #=> 48