分数小数変換の修正と逆の処理を作った@Ruby

まず、昨日書いた小数→分数のコードに不備があった。不覚。

#!/usr/bin/ruby -Ku
require 'mathn'
case readline
when /^(-?)([0-9]+)$/
  print $1, $2.to_i, $/
when /^(-?)([0-9]*)\.([0-9]*)$/
  print $1, $2.to_i + $3.to_i / 10**$3.size, $/
when /^(-?)([0-9]*)\.([0-9]*)\[([0-9]*)\]$/
  print $1, $2.to_i + $3.to_i / 10**$3.size + $4.to_i / (10**$4.size-1) / 10**$3.size, $/
end

次に、分数→小数を作った。はるかに難しいじゃねえかおい。

#!/usr/bin/ruby -Ku
require 'mathn'
class Integer
  def to_s_digits(base, digits)
    retdigs = Array.new digits
    digits.times do |i|
      retdigs[digits-i-1] = self/10**i%10 + ?0
    end
    return retdigs.pack('C*')
  end
end
case readline
when /^([0-9]*)$/
  print $1, $/
when /^([0-9]*)\/([0-9]*)$/
  frac = $1.to_i / $2.to_i
  frac -= intg = frac.to_i
  if frac == 0 then
    print intg, $/
    exit
  end
  shft = 0
  while frac.denominator%2 == 0 or frac.denominator%5 == 0
    frac *= 10
    shft += 1
  end
  frac -= fixd = frac.to_i
  p [intg, fixd, frac, shft]
  if frac == 0 then
    print intg, '.', fixd.to_s_digits(10, shft), $/
    exit
  end
  loop_digs = 1
  loop do
    break if (10**loop_digs-1) % frac.denominator == 0
    loop_digs += 1
  end
  print intg, '.', fixd.to_s_digits(10, shft), '[', ((10**loop_digs-1)*frac).to_i.to_s_digits(10, loop_digs), ']', $/
end

テストコードとかはまだ書いてない。