Skip to content

Fixes [Bug #19004]: Complex.polar handles complex singular abs argument #6568

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 23, 2022

Conversation

stevegeek
Copy link
Contributor

@stevegeek stevegeek commented Oct 16, 2022

Fixes [Bug #19004] [ruby-core:109879]

Link to issue https://bugs.ruby-lang.org/issues/19004

The issue

Complex.polar accepts Complex values as arguments for the polar form (abs, arg), as long as the value of the complex has no imaginary part (ie it is 'real' in a mathematical sense, and according to nucomp_real_p, but not necessarily real in the Ruby Numeric sense of #real?). Eg:

> Complex.polar(1+0.0i, 1+0.0i).real == Complex.polar(1, 1).real
=> true

In f_complex_polar this is handled by extracting the real part of the arguments.

However, in the case Complex.polar is called with only a single argument (ie the absolute value is given only):

> Complex.polar(1+0.0i).real
=> (1+0.0i)

The Complex is created directly without applying a check or attempting to extract the real part of abs. Thus it is possible to create a Complex where the real part is itself an instance of a Complex.

Reproduction

> Complex.polar(1+0.0i).real
=> (1+0.0i)

compare it to:

> Complex.polar(1 + 0.0i, 0.0).real
=> 1

Proposed fix

The proposed change removes the short circuit for the single argument case, meaning the real part extraction is performed by f_complex_polar as in the 2 argument case. The fact the polar argument is zero is then handled early on here in f_complex_polar anyway.

Also the switch/case is removed as it seems in other situations of a 2 argument method with optional second argument, mostly a conditional is simply used.

The spec example

Added a spec to spec/ruby/core/complex/polar_spec.rb which exposes the issue and validates the fix.

The spec aims to more generically test the specified behaviour of Complex rather than checking its internal form, hence the test creates a Complex with Complex.polar using complex arguments & then validates that the computed parts of the resulting complex number are #real?


As my first contribution please let me know if something needs changes or improvement.

Thanks for Ruby & everything you have all put into it ❤️

Fixes [Bug #19004] [ruby-core:109879]

`Complex.polar` accepts Complex values as arguments for the polar form as long
as the value of the complex has no imaginary part (ie it is 'real'). In
`f_complex_polar` this is handled by extracting the real part of the arguments.
However in the case `polar` is called with only a single argument, the absolute
value (abs), then the Complex is created without applying a check on the type
of abs, meaning it is possible to create a Complex where the real part is itself
an instance of a Complex. This change removes the short circuit for the single
argument case meaning the real part extraction is performed correctly
(by f_complex_polar).

Also adds an example to `spec/ruby/core/complex/polar_spec.rb` to check that
the real part of a complex argument is correctly extracted and used in the
resulting Complex real and imaginary parts.
@stevegeek stevegeek requested a review from nobu October 19, 2022 19:39
@nobu nobu merged commit 54cad31 into ruby:master Oct 23, 2022
@stevegeek stevegeek deleted the fix_bug_19004_on_complex_polar branch October 23, 2022 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants