[#28015] RCR: RUBY_VERSION_INT — Roger Pack <rogerdpack2@...>

Situation:

14 messages 2010/02/02

[#28113] [Bug #2723] $: length affects re-require time of already loaded files — Greg Hazel <redmine@...>

Bug #2723: $: length affects re-require time of already loaded files

16 messages 2010/02/08

[#28151] [Bug #2739] ruby 1.8.7 built with pthreads hangs under some circumstances — Joel Ebel <redmine@...>

Bug #2739: ruby 1.8.7 built with pthreads hangs under some circumstances

31 messages 2010/02/11

[#28188] [Bug #2750] build fails on win32/MinGW: "executable host ruby is required." even when --with-baseruby is used — Christian Bodt <redmine@...>

Bug #2750: build fails on win32/MinGW: "executable host ruby is required." even when --with-baseruby is used

9 messages 2010/02/16

[#28206] Is Math module a wrapper of libm? — Yusuke ENDOH <mame@...>

Hi matz --

23 messages 2010/02/18
[#28212] Re: Is Math module a wrapper of libm? — Yukihiro Matsumoto <matz@...> 2010/02/18

Hi,

[#28219] Re: Is Math module a wrapper of libm? — Yusuke ENDOH <mame@...> 2010/02/18

Hi,

[#28225] Re: Is Math module a wrapper of libm? — Marc-Andre Lafortune <ruby-core-mailing-list@...> 2010/02/18

Hi,

[#28233] Re: Is Math module a wrapper of libm? — Kenta Murata <muraken@...> 2010/02/18

Hi,

[#28265] Re: Is Math module a wrapper of libm? — Marc-Andre Lafortune <ruby-core-mailing-list@...> 2010/02/20

Hi,

[#28286] Re: Is Math module a wrapper of libm? — Kenta Murata <muraken@...> 2010/02/21

Hi

[#28291] Re: Is Math module a wrapper of libm? — Marc-Andre Lafortune <ruby-core-mailing-list@...> 2010/02/22

Hi!

[#28235] [Feature #2759] Regexp /g and /G options — Michael Fellinger <redmine@...>

Feature #2759: Regexp /g and /G options

35 messages 2010/02/18

[#28329] [ANN] Ruby 1.9.2dev has passed RubySpec! — Yusuke ENDOH <mame@...>

Hi,

12 messages 2010/02/24

[#28355] [ANN] Toward rich diversity of Ruby development. — Urabe Shyouhei <shyouhei@...>

A short announcement: thanks to some helps of GitHub people, I now have

12 messages 2010/02/27

[#28365] Indentifying key MRI-on-Windows issues — Jon <jon.forums@...>

In an effort to begin summarizing key MRI-on-Windows open issues I'm starting this thread in hopes that those interested will respond with details on the key MRI issues they feel need resolution for Windows users.

11 messages 2010/02/27
[#28690] Re: Indentifying key MRI-on-Windows issues — Roger Pack <rogerdpack2@...> 2010/03/16

> My key concern is http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-=

[ruby-core:28233] Re: Is Math module a wrapper of libm?

From: Kenta Murata <muraken@...>
Date: 2010-02-18 17:31:28 UTC
List: ruby-core #28233
Hi,

On 2010/02/19, at 0:25, Marc-Andre Lafortune wrote:

> On Thu, Feb 18, 2010 at 7:25 AM, Yusuke ENDOH <mame@tsg.ne.jp> wrote:
>> At first, I'll soon change the behaviors of atanh(1) and lgamma(inf)
>> which are currently platform-dependent.  According to SUSv3, the =
former
>> should raise ERANGE (currently raises EDOM on Linux), and the latter
>> should return inf (currently raises EDOM on darwin).
>=20
> I disagree with this reading. SUSv3 states that atanh(1) should return
> Infinity and (only when the application has requested that behavior)
> set the ERANGE error flag. Ruby must choose to do one or the other (or
> else add a way to do both). Mathematically speaking, there is no doubt
> that it should return Infinity and that this is more helpful than
> raising an error.

lgamma(x) is defined as log(fabs(tgamma(x))).
SUSv3 defines that lgamma(-INFINITY) is +INFINITY
though tgamma(-INFINITY) is defined a domain error.

Do you think what does Math.lgamma(-Float::INFINITY) return?

> The question is also valid for
> Math.log(0.0)
> Math.atanh(1.0)
> Math.gamma(0.0)
> 0.0**(-n)
>=20
> Look at the graph of 1/x. Look at the graph of Log(x). Now explain to
> me why 1/0.0 is +Inf and Log(x) would not be -Inf?


I try to write a patch for atanh, log, log2, log10, and sqrt
according to the following policies:

(1) Pick up domain and pole error cases before calling actual C =
functions.
(2) Returns NAN if a domain error is picked up.
(3) Returns INFINITY with suitable flag if a pole error is picked up.

But, I hope that a suitable exception is raised when picked up domain =
errors.
Unfortunately the existence of EDOM depends on platform.
So I believe that we need an error class like Math::DomainError.

--
Kenta Murata
OpenPGP FP =3D FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC

E-mail: mrkn@mrkn.jp
twitter: http://twitter.com/mrkn/
blog: http://d.hatena.ne.jp/mrkn/


diff --git a/math.c b/math.c
index 027932d..ebde179 100644
--- a/math.c
+++ b/math.c
@@ -310,6 +310,11 @@ math_atanh(VALUE obj, VALUE x)
     Need_Float(x);
     errno =3D 0;
     d0 =3D RFLOAT_VALUE(x);
+    /* domain error check */
+    if (d0 <  -1.0 || +1.0 <  d0) return DBL2NUM(NAN);
+    /* pole error cases */
+    if (d0 =3D=3D -1.0) return DBL2NUM(-INFINITY);
+    if (d0 =3D=3D +1.0) return DBL2NUM(+INFINITY);
     d =3D atanh(d0);
     domain_check(d0, d, "atanh");
     infinity_check(x, d, "atanh");
@@ -370,6 +375,10 @@ math_log(int argc, VALUE *argv)
     Need_Float(x);
     errno =3D 0;
     d0 =3D RFLOAT_VALUE(x);
+    /* domain error case */
+    if (signbit(d0)) return DBL2NUM(NAN);
+    /* pole error case */
+    if (d0 =3D=3D +0.0) return DBL2NUM(-INFINITY);
     d =3D log(d0);
     if (argc =3D=3D 2) {
 	Need_Float(base);
@@ -413,6 +422,10 @@ math_log2(VALUE obj, VALUE x)
     Need_Float(x);
     errno =3D 0;
     d0 =3D RFLOAT_VALUE(x);
+    /* domain error case */
+    if (signbit(d0)) return DBL2NUM(NAN);
+    /* pole error case */
+    if (d0 =3D=3D +0.0) return DBL2NUM(-INFINITY);
     d =3D log2(d0);
     domain_check(d0, d, "log2");
     infinity_check(x, d, "log2");
@@ -439,6 +452,10 @@ math_log10(VALUE obj, VALUE x)
     Need_Float(x);
     errno =3D 0;
     d0 =3D RFLOAT_VALUE(x);
+    /* domain error case */
+    if (signbit(d0)) return DBL2NUM(NAN);
+    /* pole error case */
+    if (d0 =3D=3D +0.0) return DBL2NUM(-INFINITY);
     d =3D log10(d0);
     domain_check(d0, d, "log10");
     infinity_check(x, d, "log10");
@@ -477,6 +494,8 @@ math_sqrt(VALUE obj, VALUE x)
     Need_Float(x);
     errno =3D 0;
     d0 =3D RFLOAT_VALUE(x);
+    /* domain error case */
+    if (signbit(d0)) return DBL2NUM(NAN);
     d =3D sqrt(d0);
     domain_check(d0, d, "sqrt");
     return DBL2NUM(d);
diff --git a/test/ruby/test_math.rb b/test/ruby/test_math.rb
index 5b49291..8189b31 100644
--- a/test/ruby/test_math.rb
+++ b/test/ruby/test_math.rb
@@ -2,10 +2,15 @@ require 'test/unit'
=20
 class TestMath < Test::Unit::TestCase
   def assert_infinity(a, *rest)
-    rest =3D ["not infinity"] if rest.empty?
+    rest =3D ["not infinity: #{a.inspect}"] if rest.empty?
     assert(!a.finite?, *rest)
   end
=20
+  def assert_nan(a, *rest)
+    rest =3D ["not nan: #{a.inspect}"] if rest.empty?
+    assert(a.nan?, *rest)
+  end
+
   def check(a, b)
     err =3D [Float::EPSILON * 4, [a.abs, b.abs].max * Float::EPSILON * =
256].max
     assert_in_delta(a, b, err)
@@ -99,7 +104,10 @@ class TestMath < Test::Unit::TestCase
     check(0, Math.atanh(Math.sinh(0) / Math.cosh(0)))
     check(1, Math.atanh(Math.sinh(1) / Math.cosh(1)))
     check(2, Math.atanh(Math.sinh(2) / Math.cosh(2)))
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.atanh(-1) }
+    assert_nothing_raised { assert_infinity Math.atanh(1) }
+    assert_nothing_raised { assert_infinity -Math.atanh(-1) }
+    assert_nothing_raised { assert_nan Math.atanh(1 + Float::EPSILON) }
+    assert_nothing_raised { assert_nan Math.atanh(-1 - Float::EPSILON) =
}
   end
=20
   def test_exp
@@ -116,8 +124,8 @@ class TestMath < Test::Unit::TestCase
     check(1, Math.log(10, 10))
     check(2, Math.log(100, 10))
     assert_equal(1.0/0, Math.log(1.0/0))
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log(0) }
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log(-1) }
+    assert_nothing_raised { assert_infinity -Math.log(+0.0) }
+    assert_nothing_raised { assert_nan Math.log(-0.0) }
     assert_raise(TypeError) { Math.log(1,nil) }
   end
=20
@@ -126,8 +134,8 @@ class TestMath < Test::Unit::TestCase
     check(1, Math.log2(2))
     check(2, Math.log2(4))
     assert_equal(1.0/0, Math.log2(1.0/0))
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log2(0) }
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log2(-1) }
+    assert_nothing_raised { assert_infinity -Math.log2(+0.0) }
+    assert_nothing_raised { assert_nan Math.log2(-0.0) }
   end
=20
   def test_log10
@@ -135,8 +143,8 @@ class TestMath < Test::Unit::TestCase
     check(1, Math.log10(10))
     check(2, Math.log10(100))
     assert_equal(1.0/0, Math.log10(1.0/0))
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log10(0) }
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log10(-1) }
+    assert_nothing_raised { assert_infinity -Math.log10(+0.0) }
+    assert_nothing_raised { assert_nan Math.log10(-0.0) }
   end
=20
   def test_sqrt
@@ -144,7 +152,7 @@ class TestMath < Test::Unit::TestCase
     check(1, Math.sqrt(1))
     check(2, Math.sqrt(4))
     assert_equal(1.0/0, Math.sqrt(1.0/0))
-    assert_raise(Errno::EDOM, Errno::ERANGE) { Math.sqrt(-1) }
+    assert_nothing_raised { assert_nan Math.sqrt(-0.0) }
   end
=20
   def test_frexp


In This Thread