<link rel="self" href="https://redmine.ruby-lang.org/issues/1408.atom"/>
<link rel="alternate" href="https://redmine.ruby-lang.org/"/>
<id>https://redmine.ruby-lang.org/</id>
<icon>https://redmine.ruby-lang.org/favicon.ico?1573081027</icon>
<updated>2009-04-27T09:49:03Z</updated>
<author>
<name>Ruby Issue Tracking System</name>
</author>
<entry>
<title>Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=38362009-04-27T09:49:03Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>=begin<br>
2009/4/27 Martin DeMello <a href="mailto:martindemello@gmail.com">martindemello@gmail.com</a>:</p>
<blockquote>
<p>On Sun, Apr 26, 2009 at 2:51 PM, Heesob Park <a href="mailto:redmine@ruby-lang.org">redmine@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>$ ruby -e 'p 0.1.to_r'<br>
(3602879701896397/36028797018963968)</p>
<p>whereas</p>
<p>$ ruby -e 'p "0.1".to_r'<br>
(1/10)</p>
</blockquote>
<p>What, in theory, could be done about this? By the time to_r is<br>
invoked, 0.1 is already a binary float, with the implicit rounding<br>
off.</p>
<p>In theory, Float#to_r could be done through Float#to_s#to_r.</p>
</blockquote>
<p>Regards,</p>
<p>Park Heesob</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=38372009-04-27T10:09:54Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>=begin<br>
Heesob Park wrote:</p>
<blockquote>
<p>2009/4/27 Martin DeMello <a href="mailto:martindemello@gmail.com">martindemello@gmail.com</a>:</p>
<blockquote>
<p>On Sun, Apr 26, 2009 at 2:51 PM, Heesob Park <a href="mailto:redmine@ruby-lang.org">redmine@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>$ ruby -e 'p 0.1.to_r'<br>
(3602879701896397/36028797018963968)</p>
<p>whereas</p>
<p>$ ruby -e 'p "0.1".to_r'<br>
(1/10)<br>
What, in theory, could be done about this? By the time to_r is<br>
invoked, 0.1 is already a binary float, with the implicit rounding<br>
off.</p>
</blockquote>
<p>In theory, Float#to_r could be done through Float#to_s#to_r.</p>
</blockquote>
</blockquote>
<p>-1. That loses data.</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=38662009-05-01T21:12:47Zrogerdpack (Roger Pack)rogerpack2005@gmail.com
<ul></ul><p>=begin</p>
<blockquote>
<p>-1 that loses data.</p>
</blockquote>
<p>True--however the (current) code for String#to_s attempts to determine whether the floating point number "is the equivalent default for the rounded value" (i.e. if it round trips).<br>
Do you think that using a comparisong like this (similar to what Park suggested) would be good enough for deducing the true original value? (I've thought of proposing a similar thing for BigDecimal, </p>
<p>ex: BigDecimal(0.1) => #</p>
<p>-=r<br>
=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=39222009-05-09T19:42:20Ztadf (tadayoshi funaba)
<ul></ul><p>=begin<br>
to_r should provide exact conversion.<br>
I think ruby may provide "rationalize" on common lisp or scheme.<br>
but not yet.</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=39772009-05-16T06:24:06Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>=begin<br>
Hi,</p>
<p>At Fri, 1 May 2009 21:12:52 +0900,<br>
Roger Pack wrote in [ruby-core:23345]:</p>
<blockquote>
<p>True--however the (current) code for String#to_s attempts to<br>
determine whether the floating point number "is the<br>
equivalent default for the rounded value" (i.e. if it round<br>
trips).</p>
</blockquote>
<p>What about this?</p>
<p>Index: rational.c<br>
===================================================================<br>
--- rational.c (revision 23433)<br>
+++ rational.c (working copy)<br>
@@ -1286,4 +1286,5 @@ integer_to_r(VALUE self)<br>
}</p>
<p>+#if 0<br>
static void<br>
float_decode_internal(VALUE self, VALUE *rf, VALUE *rn)<br>
@@ -1299,5 +1300,4 @@ float_decode_internal(VALUE self, VALUE <br>
}</p>
<p>-#if 0<br>
static VALUE<br>
float_decode(VALUE self)<br>
@@ -1310,11 +1310,82 @@ float_decode(VALUE self)<br>
#endif</p>
<p>+#if FLT_RADIX == 2 && SIZEOF_BDIGITS * 2 * CHAR_BIT > DBL_MANT_DIG<br>
+# ifdef HAVE_LONG_LONG<br>
+# define BDIGITDBL2NUM(x) ULL2NUM(x)<br>
+# else<br>
+# define BDIGITDBL2NUM(x) ULONG2NUM(x) <br>
+# endif<br>
+#else<br>
+# define NEEDS_FDIV<br>
+static ID id_fdiv;<br>
+fun2(fdiv)<br>
+#endif<br>
+<br>
+static VALUE<br>
+float_r_round(double a, double f, int n)<br>
+{</p>
<ul>
<li> int i, r;
+#ifdef BDIGITDBL2NUM</li>
<li> BDIGIT_DBL fn = (BDIGIT_DBL)fabs(f);</li>
<li> BDIGIT_DBL d1 = (BDIGIT_DBL)1 << -n, d2 = d1;</li>
<li> BDIGIT_DBL rv = d1 % fn;</li>
<li> VALUE b, d;</li>
<li> if (rv < 10) {</li>
<li> for (i = 1, r = (int)rv; i <= r; ++i) {</li>
<li> if ((double)fn / --d2 != a) break;</li>
<li> if (fn % (d1 = d2) == 0) break;</li>
<li> }</li>
<li> }</li>
<li> else if ((rv = fn - rv) && rv < 10) {</li>
<li> for (i = 1, r = (int)rv; i <= r; ++i) {</li>
<li> if ((double)fn / ++d2 != a) break;</li>
<li> if (fn % (d1 = d2) == 0) break;</li>
<li> }</li>
<li> }</li>
<li> b = BDIGITDBL2NUM(fn);</li>
<li> d = BDIGITDBL2NUM(d1);</li>
<li> if (f < 0) b = f_negate(b);
+#else</li>
<li> VALUE d2, fn, rv;</li>
<li> VALUE b = rb_dbl2big(f);</li>
<li> VALUE d = rb_big_pow(rb_uint2big(FLT_RADIX), INT2FIX(-n));</li>
<li> if (FIXNUM_P(d)) {</li>
<li> d = rb_uint2big(FIX2LONG(d));</li>
<li> }</li>
<li> d2 = d;</li>
<li> fn = f_abs(b);</li>
<li> rv = rb_big_modulo(d, fn);</li>
<li> if (FIXNUM_P(rv) && (r = FIX2LONG(rv)) < 10) {</li>
<li> for (i = 1; i <= r; ++i) {</li>
<li> d2 = f_sub(d2, INT2FIX(1));</li>
<li> if (RFLOAT_VALUE(f_fdiv(fn, d2)) != a) break;</li>
<li> if (f_mod(fn, d = d2) == INT2FIX(0)) break;</li>
<li> }</li>
<li> }</li>
<li> else if (FIXNUM_P(rv = f_sub(fn, rv)) && (r = FIX2LONG(rv)) < 10) {</li>
<li> for (i = 1; i <= r; ++i) {</li>
<li> d2 = f_add(d2, INT2FIX(1));</li>
<li> if (RFLOAT_VALUE(f_fdiv(fn, d2)) != a) break;</li>
<li> if (f_mod(fn, d = d2) == INT2FIX(0)) break;</li>
<li> }</li>
<li> }
+#endif</li>
<li> return rb_rational_new(b, d);
+}
+
static VALUE
float_to_r(VALUE self)
{</li>
<li> VALUE f, n;</li>
<li> double a, f;</li>
<li><p>int n;</p></li>
<li><p>float_decode_internal(self, &f, &n);</p></li>
<li><p>return f_mul(f, f_expt(INT2FIX(FLT_RADIX), n));</p></li>
<li><p>a = RFLOAT_VALUE(self);</p></li>
<li><p>f = frexp(a, &n);</p></li>
<li><p>f = ldexp(f, DBL_MANT_DIG);</p></li>
<li><p>n -= DBL_MANT_DIG;</p></li>
<li><p>if (n <= DBL_MANT_DIG && f != 0) {</p></li>
<li><p>return float_r_round(a, f, n);</p></li>
<li><p>}</p></li>
<li><p>return f_mul(rb_dbl2big(f), f_expt(INT2FIX(FLT_RADIX), INT2FIX(n)));<br>
}</p></li>
</ul>
<p>@@ -1569,4 +1640,7 @@ Init_Rational(void)<br>
id_to_s = rb_intern("to_s");<br>
id_truncate = rb_intern("truncate");<br>
+#ifdef NEEDS_FDIV</p>
<ul>
<li><p>id_fdiv = rb_intern("fdiv");<br>
+#endif</p>
<p>ml = (long)(log(DBL_MAX) / log(2.0) - 1);<br>
�</p></li>
</ul>
<p>-- <br>
Nobu Nakada</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=40002009-05-18T11:15:28Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>=begin<br>
Hi,</p>
<p>In message "Re: [ruby-core:23465] Re: [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: 0.1.to_r not equal to (1/10) (Closed)" href="https://redmine.ruby-lang.org/issues/1408">#1408</a>] 0.1.to_r not equal to (1/10)"<br>
on Sat, 16 May 2009 06:23:53 +0900, Nobuyoshi Nakada <a href="mailto:nobu@ruby-lang.org">nobu@ruby-lang.org</a> writes:</p>
<p>|What about this?</p>
<p>Could you explain how this patch differs from the original?</p>
<pre> matz.
</pre>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=40012009-05-18T11:49:23Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>=begin<br>
Hi,</p>
<p>At Mon, 18 May 2009 11:15:16 +0900,<br>
Yukihiro Matsumoto wrote in [ruby-core:23487]:</p>
<blockquote>
<p>Could you explain how this patch differs from the original?</p>
</blockquote>
<p>Searches more reduceable numerator which can round trip. Since<br>
it just tries the numerator only in very restricted condtion,<br>
better result may be achieved by trying also the denominator,<br>
in other cases. In fact, the patch works for very simple<br>
cases, e.g. 0.1 and (1.0/3.0), but doesn't for 0.24.</p>
<p>-- <br>
Nobu Nakada</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=46692009-07-14T00:06:42Zyugui (Yuki Sonoda)yugui@yugui.jp
<ul><li><strong>Target version</strong> changed from <i>1.9.1</i> to <i>1.9.2</i></li></ul><p>=begin</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=58632009-09-18T04:53:17Zmarcandre (Marc-Andre Lafortune)ruby-core@marc-andre.ca
<ul><li><strong>Category</strong> set to <i>core</i></li><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li></ul><p>=begin</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=59112009-09-20T13:17:07Zmarcandre (Marc-Andre Lafortune)ruby-core@marc-andre.ca
<ul></ul><p>=begin<br>
Sorry to be late to the party on this one.</p>
<p>It is important to remember that a Float is always an approximation.</p>
<p>1.0 has to be understood as 1.0 +/- EPSILON, where the EPSILON is platform dependent. 1.0 is not more equal to 1 than to 1 + EPSILON/2. Indeed, there is no way to distinguish either when they are stored as floats.</p>
<p>To believe that Float#to_s loses data is wrong. If r.to_s returns "1.2", it implies that 1.2 is one of the values in the range of possible values for that floating number. It could have been 1.2000...0006. Or something else. There is no way to know, so #to_s chooses, wisely, to return the simplest value in the range.</p>
<p>There are many rationals that would be encoded as floats the same way. There is no magic way to know that the "exact" value was exactly 12/10 or 5404319552844595/4503599627370496, or anything in between. All have the same representation as a float. There is no reason to believe that the missing (binary) decimals that couldn't be written in space allowed where all 0. Actually, there is reason to believe that they were <u>probably</u> non zero, because fractions that can not be expressed with a finite number of terms in their expansion in a given base all have a recurring expansion. I.e. if the significand does not end with a whole bunch of zeros (rational has finite expansion) then it probably ends with an infinite pattern (say 011011011 in binary, or 333333 in decimal).</p>
<p>For any given float, there is one and only one rational with the smallest denominator that falls in the range of its possible values. It is currently given by Number#rationalize, and I really do not understand why #to_r would return anything else. </p>
<p>I cannot see any purpose to any other fraction. Moreover, the current algorithm, which returns the middle of the range of possibilities, is platform dependent since the range of possibilities is platform dependent. That makes it even less helpful.</p>
<p>Is there an example where one would want 0.1.to_r to be 3602879701896397/36028797018963968 ?<br><br>
Do we really think that 0.1.to_r to be 3602879701896397/36028797018963968 corresponds to the principle of least surprise?<br>
Note that I'm writing that fraction but with a different native double encoding, the fraction would be different.</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=96772010-04-02T08:19:17Zznz (Kazuhiro NISHIYAMA)
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Target version</strong> changed from <i>1.9.2</i> to <i>2.0.0</i></li></ul><p>=begin</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=101292010-04-12T22:16:22Zmarcandre (Marc-Andre Lafortune)ruby-core@marc-andre.ca
<ul></ul><p>=begin<br>
Why isn't Float#to_r simply calling Float#rationalize ?</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=102822010-04-18T15:17:30Zmwaechter (Matthias Wächter)matthias@waechter.wiz.at
<ul></ul><p>=begin<br>
Am 20.09.2009 06:17, schrieb Marc-Andre Lafortune:</p>
<blockquote>
<p>Sorry to be late to the party on this one.</p>
</blockquote>
<p>I’m late as well ;)</p>
<blockquote>
<p>It is important to remember that a Float is always an approximation.</p>
</blockquote>
<p>No. It is an approximation only for:</p>
<p>• conversion from most decimal numbers, especially floats, and<br>
• calculations that drop digits.</p>
<p>You can do exact math in a limited range of operations, and the question <br>
should be whether the approximation approach should overrule this exact <br>
math range of use, especially considering that conversion back to <br>
decimal <u>could</u> be done precisely, however, sometimes requiring a bunch <br>
of digits.</p>
<blockquote>
<p>1.0 has to be understood as 1.0 +/- EPSILON, where the EPSILON is platform<br>
dependent. 1.0 is not more equal to 1 than to 1 + EPSILON/2. Indeed, there<br>
is no way to distinguish either when they are stored as floats.</p>
</blockquote>
<p>If what’s stored in the Float <u>is</u> your precise result, you certainly <br>
would not ask for precision reduction just because it <u>could</u> have been <br>
the result of an imprecise calculation.</p>
<blockquote>
<p>To believe that Float#to_s loses data is wrong.</p>
</blockquote>
<p>I think there should be both a Float#to_s and Float#to_nearest_s. The <br>
first would be precise, the second would output the “shortest” decimal <br>
representation within ±EPSILON/2.</p>
<blockquote>
<p>If r.to_s returns "1.2", it implies that 1.2 is one of the values in the<br>
range of possible values for that floating number. It could have been<br>
1.2000...0006. Or something else. There is no way to know, so #to_s chooses,<br>
wisely, to return the simplest value in the range.</p>
</blockquote>
<p>This is based on the assumption that no-one would ever care about <br>
Float’s precision.</p>
<blockquote>
<p>There are many rationals that would be encoded as floats the same way. There<br>
is no magic way to know that the "exact" value was exactly 12/10 or<br>
5404319552844595/4503599627370496, or anything in between. All have the same<br>
representation as a float. There is no reason to believe that the missing<br>
(binary) decimals that couldn't be written in space allowed where all 0.<br>
Actually, there is reason to believe that they were <u>probably</u> non zero,<br>
because fractions that can not be expressed with a finite number of terms in<br>
their expansion in a given base all have a recurring expansion. I.e. if the<br>
significand does not end with a whole bunch of zeros (rational has finite<br>
expansion) then it probably ends with an infinite pattern (say 011011011 in<br>
binary, or 333333 in decimal).</p>
<p>For any given float, there is one and only one rational with the smallest<br>
denominator that falls in the range of its possible values. It is currently<br>
given by Number#rationalize, and I really do not understand why #to_r would<br>
return anything else.</p>
<p>I cannot see any purpose to any other fraction. Moreover, the current algorithm,<br>
which returns the middle of the range of possibilities, is platform dependent<br>
since the range of possibilities is platform dependent. That makes it even less<br>
helpful.</p>
<p>Is there an example where one would want 0.1.to_r to be<br>
3602879701896397/36028797018963968 ?</p>
</blockquote>
<p>If the binary/Float’s representation of <br>
3602879701896397/36028797018963968 is the real result of the <br>
calculation? How do you know?</p>
<blockquote>
<p>Do we really think that 0.1.to_r to be 3602879701896397/36028797018963968<br>
corresponds to the principle of least surprise?</p>
</blockquote>
<p>False assumption here. Using floats for exact decimal math already <br>
violates POLS. Don’t blame the messenger, i.e. the converter back to <br>
decimal, the only part of the game that could <u>always</u> be precise.</p>
<blockquote>
<p>Note that I'm writing that fraction but with a different native double<br>
encoding, the fraction would be different.</p>
</blockquote>
<p>Sure. Great to have different levels of precision/imprecision from the <br>
computers.</p>
<p>And portability is not always the issue, otherwise there would have <br>
never been different native floating point precisions.</p>
<p>– Matthias</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=103282010-04-19T17:12:16Zmwaechter (Matthias Wächter)matthias@waechter.wiz.at
<ul></ul><p>=begin<br>
Hello Marc-Andre,</p>
<p>On 19.04.2010 00:14, Marc-Andre Lafortune wrote:</p>
<blockquote>
<p>I hope my dissent will not sound too harsh.</p>
</blockquote>
<p>Not at all.</p>
<blockquote>
<p>Arguing that 0.1.to_r should be 3602879701896397/36028797018963968 is<br>
the same as arguing that 0.1.to_s should outputs these 55 decimals.</p>
</blockquote>
<p>Right, that’s my point. 0.1 as a Float has a precise meaning in binary as in decimal, so Float#to_s should keep those 55 decimals. That’s why I said<br>
that Float#to_nearest_s – choose a better name or an option to Fload#to_s – should be created that does »what everyone expects« to_s to do.</p>
<p>The same applies to Float#to_r. It should be as precise as possible, which it is currently. The function that does »what everyone expects« should be<br>
Float#to_nearest_r in the same way as for the string representation.</p>
<blockquote>
<p>For these reasons, the set S is of little interest to anybody.</p>
</blockquote>
<p>The problem is that most people think that Floating point arithmetic is precise, which it is only for the the cases I described in my last mail.</p>
<blockquote>
<p>What <em>is</em> interesting is the set of real numbers. Floating numbers are<br>
used to represent them <em>approximately</em>. To add to my voice, here are a<br>
couple of excerpts from the first links that come up on google<br>
(highlight mine):</p>
<p>"In computing, floating point describes a system for representing<br>
numbers that would be too large or too small to be represented as<br>
integers. Numbers are in general represented <em>approximately</em> to a<br>
fixed number of significant digits and scaled using an exponent."<br>
<a href="http://en.wikipedia.org/wiki/Floating_point">http://en.wikipedia.org/wiki/Floating_point</a></p>
<p>"Squeezing infinitely many real numbers into a finite number of bits<br>
requires an <em>approximate</em> representation.... Therefore the result of a<br>
floating-point calculation must often be rounded in order to fit back<br>
into its finite representation. This rounding error is the<br>
characteristic feature of floating-point computation." source:<br>
<a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html">http://docs.sun.com/source/806-3568/ncg_goldberg.html</a></p>
</blockquote>
<p>That’s where the problem starts. Everyone thinks he can do exact math on a computer, and the only problem was the approximation of the binary<br>
representation of a real number, characterized by ±EPSILON/2. No, the <u>real</u> issue is the approximation of calculations which not only accumulates<br>
EPSILON with each calculation, but it can shift EPSILON to any order. Think of something trivial like (1E-40+0.1-0.1) returning 0.0 vs.<br>
(1E-40+0.3-0.2-0.1) returning -2.7E-17. There is no real math in floats.</p>
<p>One can go as far as saying that availability of math-like operators and math-like precedence in a programming language supports the expectations of<br>
real-number-like behavior and precision. But this is slightly off-topic, and in fact method calls for simple math are not doing any good to<br>
readability. Math-like operator precedence is different and something completely unnecessary in a programming language, IMHO.</p>
<blockquote>
<p>Note that typing 0.1 in Ruby is a "calculation" which consists in<br>
finding the member of S closest to 1/10.</p>
<p>Your final question was: how do I know that the value someone is<br>
talking about is 0.1 and not<br>
0.1000000000000000055511151231257827021181583404541015625 (or<br>
equivalently 3602879701896397/36028797018963968) ?</p>
<p>I call it common sense.</p>
</blockquote>
<p>It looks so obvious when we are talking about 0.1. If we talk about any other number with 80 digits, my point may become clearer.</p>
<p>What do you do if it’s not 0.1 a.k.a. 0.1000000000000000055511151231257827021181583404541015625 but<br>
0.09999999999999997779553950749686919152736663818359375 (the result of (0.3-0.2)? What’s the difference for your argument? Now we will not get back<br>
the expected nearest 0.1 anyway without applying the actually required/expected rounding constraints.</p>
<p>If it’s just about 0.1.to_r, i.e. converting from a decimal constant number to rational, use String#to_r.</p>
<p>Bottom line: Floats are not exact in terms of math, but they are exact in terms of computer-level implementation, implementing IEEE 754. We should<br>
respect the latter and help people deal with the former.</p>
<p>– Matthias</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=103602010-04-20T20:02:16Ztadf (tadayoshi funaba)
<ul></ul><p>=begin</p>
<blockquote>
<p>Why isn't Float#to_r simply calling Float#rationalize ?</p>
</blockquote>
<p>a = 0.5337486539516013<br>
b = 0.5337486539516012</p>
<p>a == b #=> false</p>
<p>a.to_r == a #=> true<br>
a.rationalize == a #=> false</p>
<p>a.to_r == b #=> false<br>
a.rationalize == b #=> true</p>
<p>actually, flonum is restricted rational number.<br>
however, rationalize bends the value.</p>
<p>to_r is the simplest and the cheapest way, rationalize is not so.</p>
<p>moreover, various languages support exact conversion (e.g. CL, Scheme, Haskell, Squeak, Python).</p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=108172010-05-06T12:37:59Zmrkn (Kenta Murata)muraken@gmail.com
<ul></ul><p>=begin<br>
Float#rationalize is added again at r27503.<br>
Please check that revision.</p>
<p>On 2010/05/06, at 7:23, Marc-Andre Lafortune wrote:</p>
<blockquote>
<p>Maybe a kind Japanese reader can provide the gist of [ruby-dev:41061]<br>
to explain why was Float#rationalize removed?</p>
<p>I would also appreciate opinions as to why it wouldn't be a net<br>
improvement if to_r used the rationalize algorithm and some other<br>
methods were provided for anyone wanting the value of the<br>
representation (e.g. Float#representation which would return [sign,<br>
mantissa, significand] and/or Float#representation_to_r would give the<br>
rational corresponding to the internal representation of that float)</p>
</blockquote>
<p>--<br>
Kenta Murata<br>
OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC</p>
<p>E-mail: <a href="mailto:mrkn@mrkn.jp">mrkn@mrkn.jp</a><br>
twitter: <a href="http://twitter.com/mrkn/">http://twitter.com/mrkn/</a><br>
blog: <a href="http://d.hatena.ne.jp/mrkn/">http://d.hatena.ne.jp/mrkn/</a></p>
<p>=end</p>
Ruby master - Feature #1408: 0.1.to_r not equal to (1/10)https://redmine.ruby-lang.org/issues/1408?journal_id=204642011-08-29T09:32:10Zmrkn (Kenta Murata)muraken@gmail.com
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>I close this ticket because the topic was too diverged.<br>
Would you please make new tickets for the new version of ruby if anyone has objections.</p>