Forum: Ruby-core [ruby-trunk - Feature #8850][Assigned] Convert Rational to decimal string

9361878d459f1709feec780518946ee5?d=identicon&s=25 naruse (Yui NARUSE) (Guest)
on 2013-09-02 03:03
(Received via mailing list)
Issue #8850 has been reported by naruse (Yui NARUSE).

----------------------------------------
Feature #8850: Convert Rational to decimal string
https://bugs.ruby-lang.org/issues/8850

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (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
Df9d48b6e2ae6cdedf4c39c2e58df851?d=identicon&s=25 boris_stitnicky (Boris Stitnicky) (Guest)
on 2013-09-03 04:12
(Received via mailing list)
Issue #8850 has been updated by boris_stitnicky (Boris Stitnicky).


How about to_s( :decimal ) ?
----------------------------------------
Feature #8850: Convert Rational to decimal string
https://bugs.ruby-lang.org/issues/8850#change-41548

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (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
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (nobu)
on 2014-02-14 09:53
(Received via mailing list)
Issue #8850 has been updated by Nobuyoshi Nakada.

Description updated

----------------------------------------
Feature #8850: Convert Rational to decimal string
https://bugs.ruby-lang.org/issues/8850#change-45145

* Author: Yui NARUSE
* Status: Assigned
* 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
```
9d2f78236e45a335301ba1195026105d?d=identicon&s=25 unknown (Guest)
on 2014-02-14 09:54
(Received via mailing list)
Issue #8850 has been updated by Shyouhei Urabe.

Status changed from Assigned to Feedback

Can anyone propose a patch please?

----------------------------------------
Feature #8850: Convert Rational to decimal string
https://bugs.ruby-lang.org/issues/8850#change-45146

* 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
```
7cca11c5257fda526eeb4b1ada28f904?d=identicon&s=25 unknown (Guest)
on 2014-02-15 16:21
(Received via mailing list)
Issue #8850 has been updated by Kenta Murata.


I made a simple implementation:
https://github.com/mrkn/ruby/commit/408d4a05c40a70...

----------------------------------------
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
```
7cca11c5257fda526eeb4b1ada28f904?d=identicon&s=25 unknown (Guest)
on 2014-02-16 06:20
(Received via mailing list)
Issue #8850 has been updated by Kenta Murata.

Status changed from Feedback to Assigned

----------------------------------------
Feature #8850: Convert Rational to decimal string
https://bugs.ruby-lang.org/issues/8850#change-45196

* Author: Yui NARUSE
* Status: Assigned
* 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
```
7cca11c5257fda526eeb4b1ada28f904?d=identicon&s=25 unknown (Guest)
on 2014-02-16 15:14
(Received via mailing list)
Issue #8850 has been updated by Kenta Murata.


I updated the patch to use rb_check_arity:
https://github.com/mrkn/ruby/commit/a6837fab190fed...

----------------------------------------
Feature #8850: Convert Rational to decimal string
https://bugs.ruby-lang.org/issues/8850#change-45197

* Author: Yui NARUSE
* Status: Assigned
* 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
```
7cca11c5257fda526eeb4b1ada28f904?d=identicon&s=25 unknown (Guest)
on 2014-02-17 23:46
(Received via mailing list)
Issue #8850 has been updated by Kenta Murata.


I've updated the patch by rebasing and fixing syntax.
https://github.com/mrkn/ruby/compare/64634f92f3474...

----------------------------------------
Feature #8850: Convert Rational to decimal string
https://bugs.ruby-lang.org/issues/8850#change-45223

* Author: Yui NARUSE
* Status: Assigned
* 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
```
This topic is locked and can not be replied to.