Project

General

Profile

Feature #8850

Updated by nobu (Nobuyoshi Nakada) almost 11 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