分数小数変換をモジュール化してテストを作ってみた
Rubyでテストケース作るのはじめて。
テストケースの書き方がわかりやすくていいね。
変えたこと
- まず、readline→printというルーチンから、引数→戻り値というルーチンにした。
- それをRationalのメソッドとして組み込んだ。
- mathn.rbはシステム全体に影響を与えるので使用しないようにした。
- テストケースを作った。
#repeating-decimal.rb require 'rational' 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 class Rational def self.from_rd(s) case s when /^(-?)([0-9]+)$/ return s.to_i.to_r when /^(-?)([0-9]*)\.([0-9]*)$/ return ($1+$2).to_i + ($1+$3).to_i.to_r / 10**$3.size when /^(-?)([0-9]*)\.([0-9]*)\[([0-9]*)\]$/ return ($1+$2).to_i + ( ($1+$3).to_i.to_r + ($1+$4).to_i.to_r / (10**$4.size-1) ) / 10**$3.size else return nil end end def to_rd frac = self sign = "" if frac < 0 then sign = "-" frac = -frac end frac -= intg = frac.to_i if frac == 0 then return sign + intg.to_s 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 return sign + intg.to_s + '.' + 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 return sign + intg.to_s + '.' + fixd.to_s_digits(10, shft) + '[' + ((10**loop_digs-1)*frac).to_i.to_s_digits(10, loop_digs) + ']' end end
#!/usr/bin/ruby -Ku #rdtest.rb require "runit/testcase" require "runit/cui/testrunner" require "repeating-decimal" class RDTest < RUNIT::TestCase def test1 assert_equal(Rational(0,1), Rational.from_rd("0")) end def test2 assert_equal(Rational(-0,1), Rational.from_rd("-0")) end def test3 assert_equal(Rational(11,10), Rational.from_rd("1.1")) end def test4 assert_equal(Rational(-11,10), Rational.from_rd("-1.1")) end def test5 assert_equal(Rational(1,3), Rational.from_rd("0.[3]")) end def test6 assert_equal(Rational(-1,3), Rational.from_rd("-0.[3]")) end def test7 assert_equal(Rational(1,6), Rational.from_rd("0.1[6]")) end def test8 assert_equal(Rational(-1,6), Rational.from_rd("-0.1[6]")) end def test9 assert_equal(Rational(0,1).to_rd, "0") end def test10 #assert_equal(Rational(-0,1).to_rd, "-0") end def test11 assert_equal(Rational(11,10).to_rd, "1.1") end def test12 assert_equal(Rational(-11,10).to_rd, "-1.1") end def test13 assert_equal(Rational(1,3).to_rd, "0.[3]") end def test14 assert_equal(Rational(-1,3).to_rd, "-0.[3]") end def test15 assert_equal(Rational(1,6).to_rd, "0.1[6]") end def test16 assert_equal(Rational(-1,6).to_rd, "-0.1[6]") end end RUNIT::CUI::TestRunner.run(RDTest.suite)