[前][次][番号順一覧][スレッド一覧]

ruby-changes:33724

From: nobu <ko1@a...>
Date: Sun, 4 May 2014 10:23:09 +0900 (JST)
Subject: [ruby-changes:33724] nobu:r45805 (trunk): math.c: C99-like atan2

nobu	2014-05-04 10:23:01 +0900 (Sun, 04 May 2014)

  New Revision: 45805

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45805

  Log:
    math.c: C99-like atan2
    
    * math.c (math_atan2): return values like as expected by C99 if
      both two arguments are infinity.  based on the patch by cremno
      phobia <cremno AT mail.ru> in [ruby-core:62310].  [Feature #9799]

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/configure.in
    trunk/math.c
    trunk/test/ruby/test_math.rb
Index: math.c
===================================================================
--- math.c	(revision 45804)
+++ math.c	(revision 45805)
@@ -55,6 +55,10 @@ VALUE rb_eMathDomainError; https://github.com/ruby/ruby/blob/trunk/math.c#L55
  *    Math.atan2(1.0, 0.0)   #=> 1.5707963267948966
  *    Math.atan2(1.0, -1.0)  #=> 2.356194490192345
  *    Math.atan2(0.0, -1.0)  #=> 3.141592653589793
+ *    Math.atan2(INFINITY, INFINITY)   #=> 0.7853981633974483
+ *    Math.atan2(INFINITY, -INFINITY)  #=> 2.356194490192345
+ *    Math.atan2(-INFINITY, INFINITY)  #=> -0.7853981633974483
+ *    Math.atan2(-INFINITY, -INFINITY) #=> -2.356194490192345
  *
  */
 
@@ -75,7 +79,20 @@ math_atan2(VALUE obj, VALUE y, VALUE x) https://github.com/ruby/ruby/blob/trunk/math.c#L79
 	    return DBL2NUM(M_PI);
 	return DBL2NUM(-M_PI);
     }
-    if (isinf(dx) && isinf(dy)) domain_error("atan2");
+#if !(defined(HAVE_ATAN2L) && defined(HAVE_ATAN2F)) || 1
+    /* assume atan2() doesn't handle Inf as C99 */
+    if (isinf(dx) && isinf(dy)) {
+	/* optimization for FLONUM */
+	if (dx < 0.0) {
+	    const double dz = (3.0 * M_PI / 4.0);
+	    return (dy < 0.0) ? DBL2NUM(-dz) : DBL2NUM(dz);
+	}
+	else {
+	    const double dz = (M_PI / 4.0);
+	    return (dy < 0.0) ? DBL2NUM(-dz) : DBL2NUM(dz);
+	}
+    }
+#endif
     return DBL2NUM(atan2(dy, dx));
 }
 
Index: configure.in
===================================================================
--- configure.in	(revision 45804)
+++ configure.in	(revision 45805)
@@ -1941,6 +1941,7 @@ AC_CHECK_FUNCS(__syscall) https://github.com/ruby/ruby/blob/trunk/configure.in#L1941
 AC_CHECK_FUNCS(_longjmp)		# used for AC_ARG_WITH(setjmp-type)
 AC_CHECK_FUNCS(_setjmp)			# used for AC_ARG_WITH(setjmp-type)
 AC_CHECK_FUNCS(_setjmpex)		# used for AC_ARG_WITH(setjmp-type)
+AC_CHECK_FUNCS(atan2l atan2f)
 AC_CHECK_FUNCS(chroot)
 AC_CHECK_FUNCS(chsize)
 AC_CHECK_FUNCS(clock_gettime)
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45804)
+++ ChangeLog	(revision 45805)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun May  4 10:22:59 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* math.c (math_atan2): return values like as expected by C99 if
+	  both two arguments are infinity.  based on the patch by cremno
+	  phobia <cremno AT mail.ru> in [ruby-core:62310].  [Feature #9799]
+
 Sun May  4 03:46:42 2014  Tanaka Akira  <akr@f...>
 
 	* lib/time.rb (Time.httpdate): Always return a UTC Time object.
Index: NEWS
===================================================================
--- NEWS	(revision 45804)
+++ NEWS	(revision 45805)
@@ -54,6 +54,8 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L54
     * Math.log now raises Math::DomainError instead of returning NaN if the
       base is less than 0, and returns NaN instead of -infinity if both of
       two arguments are 0.
+    * Math.atan2 now returns values like as expected by C99 if both two
+      arguments are infinity.
 
 * Proc
   * incompatible changes:
Index: test/ruby/test_math.rb
===================================================================
--- test/ruby/test_math.rb	(revision 45804)
+++ test/ruby/test_math.rb	(revision 45805)
@@ -22,10 +22,15 @@ class TestMath < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_math.rb#L22
     check(-0.0, Math.atan2(-0.0, +0.0))
     check(+Math::PI, Math.atan2(+0.0, -0.0))
     check(-Math::PI, Math.atan2(-0.0, -0.0))
-    assert_raise(Math::DomainError) { Math.atan2(Float::INFINITY, Float::INFINITY) }
-    assert_raise(Math::DomainError) { Math.atan2(Float::INFINITY, -Float::INFINITY) }
-    assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, Float::INFINITY) }
-    assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, -Float::INFINITY) }
+
+    inf = Float::INFINITY
+    expected = 3.0 * Math::PI / 4.0
+    assert_nothing_raised { check(+expected, Math.atan2(+inf, -inf)) }
+    assert_nothing_raised { check(-expected, Math.atan2(-inf, -inf)) }
+    expected = Math::PI / 4.0
+    assert_nothing_raised { check(+expected, Math.atan2(+inf, +inf)) }
+    assert_nothing_raised { check(-expected, Math.atan2(-inf, +inf)) }
+
     check(0, Math.atan2(0, 1))
     check(Math::PI / 4, Math.atan2(1, 1))
     check(Math::PI / 2, Math.atan2(1, 0))

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]