From: muraken@... Date: 2014-02-15T15:20:50+00:00 Subject: [ruby-core:60765] [ruby-trunk - Feature #8850] Convert Rational to decimal string Issue #8850 has been updated by Kenta Murata. I made a simple implementation: https://github.com/mrkn/ruby/commit/408d4a05c40a70a7d49e40d6edc33af98e6816a3 ---------------------------------------- Feature #8850: Convert Rational to decimal string https://bugs.ruby-lang.org/issues/8850#change-45182 * Author: Yui NARUSE * Status: Feedback * Priority: Normal * Assignee: Yukihiro Matsumoto * Category: * Target version: next minor ---------------------------------------- On Ruby 2.1.0, decimal literal is introduced. It generates Rational but it cannot easily convert to decimal string. You know, Rational#to_f is related to this but * Float is not exact number ** 0.123456789123456789r.to_f.to_s #=> "0.12345678912345678" * it can't handle recursive decimal ** (151/13r).to_f.to_s #=> "11.615384615384615" * the method name ** to_decimal ** to_decimal_string ** to_s(format: :decimal) ** extend sprintf * how does it express recursive decimal ** (151/13r).to_decimal_string #=> "11.615384..." ** (151/13r).to_decimal_string #=> "11.(615384)" Example implementation is following. Its result is ** 0.123456789123456789r.to_f.to_s #=> "0.123456789123456789" ** (151/13r).to_f.to_s #=> "11.(615384)" ``` class Rational def to_decimal_string(base=10) n = numerator d = denominator r, n = n.divmod d str = r.to_s(base) return str if n == 0 h = {} str << '.' n *= base str.size.upto(Float::INFINITY) do |i| r, n = n.divmod d if n == 0 str << r.to_s(base) break elsif h.key? n str[h[n], 0] = '(' str << ')' break else str << r.to_s(base) h[n] = i n *= base end end str end end ``` -- http://bugs.ruby-lang.org/