## Feature #9799

### change behavior of Math::atan2 if y and x are both Float::INFINITY

**Description**

The current behavior when y and x are either negative or positive infinity is:

```
Math.atan2(Float::INFINITY, Float::INFINITY) # raises Math::DomainError
```

The attached diff changes it to:

```
Math.atan2(Float::INFINITY, Float::INFINITY) # => 0.7853981633974483
```

I think a domain error isn't desirable here. Is it even one? Other languages like Go, Python, Java or Javascript seem to return the expected result. .NET languages return NaN.

ISO C99/C11 also does, if the implementation follows the normative Annex F. This isn't always the case, but there is already a special case when y and x are zero, so I think this one is acceptable, too.

http://golang.org/src/pkg/math/atan2.go

http://hg.python.org/cpython/file/62438d1b11c7/Modules/mathmodule.c#l516

http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#atan2%28double,%20double%29

http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.5

http://port70.net/~nsz/c/c99/n1256.html#F.9.1.4

http://msdn.microsoft.com/en-us/library/system.math.atan2.aspx

### Associated revisions

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 in . [Feature #9799]

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 in . [Feature #9799]

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 in . [Feature #9799]

### History

#### #1 [ruby-core:62333] Updated by Nobuyoshi Nakada over 2 years ago

**Category**set to*core***Tracker**changed from*Bug*to*Feature*

#### #2 [ruby-core:62334] Updated by Yusuke Endoh over 2 years ago

Interesting. I'm not against the change since the proposed behavior looks prevailing, but I wonder if it is useful that the following case returns pi/4.

```
x = Float::INFINITY
Math.atan2(x, 2 * x) #=> Math::PI/4, not Math.atan2(1, 2)
```

--

Yusuke Endoh mame@tsg.ne.jp

#### #3 [ruby-core:62335] Updated by Nobuyoshi Nakada over 2 years ago

**Status**changed from*Open*to*Closed***% Done**changed from*0*to*100*

#### #4 [ruby-core:62336] Updated by Nobuyoshi Nakada over 2 years ago

Yusuke Endoh wrote:

Interesting. I'm not against the change since the proposed behavior looks prevailing, but I wonder if it is useful that the following case returns pi/4.

Yes, I wondered it too

But `Float::INFINITY == Float::INFINITY*2`

also returns `true`

, it doesn't feel worth to worry about.

#### #5 [ruby-core:62338] Updated by cremno phobia over 2 years ago

I've searched for a rationale. It can be found in http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf on the bottom of page 188 (or real page 181):

The specification of

`atan2(∞,∞)`

as`π/4`

indicates the reasonable quadrant, preserving some information in preference to none.

Maybe it does make more sense **for Ruby** to raise. I'm not a mathematician and it also doesn't look useful to me. Also, some languages I've linked seem to lack a similar exception/error (Go or JS), but instead of returning NaN, they follow C's Ann. F and return a more meaningful result instead.

It is mainly curiosity (I've added `Math::DomainError`

to mruby)—I don't have a strong opinion on this.

#### #6 [ruby-core:62356] Updated by Marcus Stollsteimer over 2 years ago

Wait, wait...

So you introduce mathematically wrong behaviour with the argument that there already is some other wrong behaviour???

#### #7 [ruby-core:62368] Updated by cremno phobia over 2 years ago

Marcus Stollsteimer wrote:

Wait, wait...

So you introduce mathematically wrong behaviour with the argument that there already is some other wrong behaviour???

I don't consider it wrong for a programming language. Maybe these special cases make less sense than the other ones, but they exist in many other languages. Even in numerical ones. That is my argument. But as I've said I'd be okay with the uncommon choice of not having them.

Julia (a nice language, by the way):

julia> atan2(Inf, Inf) 0.7853981633974483 julia> atan2(BigFloat(Inf), BigFloat(Inf)) 7.853981633974483096156608458198757210492923498437764552437361480769541015715495 e-01 with 256 bits of precision

GNU Octave: https://www.gnu.org/software/octave/doc/interpreter/Trigonometry.html

NumPy: http://docs.scipy.org/doc/numpy/reference/generated/numpy.arctan2.html