Project

General

Profile

Feature #8850

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

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 
 ```

Back