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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45805 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6e34259271
commit
7a6ebecf9e
@ -1,3 +1,9 @@
|
|||||||
|
Sun May 4 10:22:59 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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@fsij.org>
|
Sun May 4 03:46:42 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* lib/time.rb (Time.httpdate): Always return a UTC Time object.
|
* lib/time.rb (Time.httpdate): Always return a UTC Time object.
|
||||||
|
2
NEWS
2
NEWS
@ -54,6 +54,8 @@ with all sufficient information, see the ChangeLog file.
|
|||||||
* Math.log now raises Math::DomainError instead of returning NaN if the
|
* 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
|
base is less than 0, and returns NaN instead of -infinity if both of
|
||||||
two arguments are 0.
|
two arguments are 0.
|
||||||
|
* Math.atan2 now returns values like as expected by C99 if both two
|
||||||
|
arguments are infinity.
|
||||||
|
|
||||||
* Proc
|
* Proc
|
||||||
* incompatible changes:
|
* incompatible changes:
|
||||||
|
@ -1941,6 +1941,7 @@ AC_CHECK_FUNCS(__syscall)
|
|||||||
AC_CHECK_FUNCS(_longjmp) # used for AC_ARG_WITH(setjmp-type)
|
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(_setjmp) # used for AC_ARG_WITH(setjmp-type)
|
||||||
AC_CHECK_FUNCS(_setjmpex) # 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(chroot)
|
||||||
AC_CHECK_FUNCS(chsize)
|
AC_CHECK_FUNCS(chsize)
|
||||||
AC_CHECK_FUNCS(clock_gettime)
|
AC_CHECK_FUNCS(clock_gettime)
|
||||||
|
19
math.c
19
math.c
@ -55,6 +55,10 @@ VALUE rb_eMathDomainError;
|
|||||||
* Math.atan2(1.0, 0.0) #=> 1.5707963267948966
|
* Math.atan2(1.0, 0.0) #=> 1.5707963267948966
|
||||||
* Math.atan2(1.0, -1.0) #=> 2.356194490192345
|
* Math.atan2(1.0, -1.0) #=> 2.356194490192345
|
||||||
* Math.atan2(0.0, -1.0) #=> 3.141592653589793
|
* 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)
|
|||||||
return DBL2NUM(M_PI);
|
return DBL2NUM(M_PI);
|
||||||
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));
|
return DBL2NUM(atan2(dy, dx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +22,15 @@ class TestMath < Test::Unit::TestCase
|
|||||||
check(-0.0, Math.atan2(-0.0, +0.0))
|
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))
|
||||||
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) }
|
inf = Float::INFINITY
|
||||||
assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, Float::INFINITY) }
|
expected = 3.0 * Math::PI / 4.0
|
||||||
assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, -Float::INFINITY) }
|
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(0, Math.atan2(0, 1))
|
||||||
check(Math::PI / 4, Math.atan2(1, 1))
|
check(Math::PI / 4, Math.atan2(1, 1))
|
||||||
check(Math::PI / 2, Math.atan2(1, 0))
|
check(Math::PI / 2, Math.atan2(1, 0))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user