Skip to content

Fix complex.__repr__ handling of nan - #3184

Closed
mdegis wants to merge 1 commit into
RustPython:mainfrom
mdegis:fix/complex_repr
Closed

mdegis wants to merge 1 commit into
RustPython:mainfrom
mdegis:fix/complex_repr

Conversation

@mdegis

@mdegis mdegis commented Oct 1, 2021

Copy link
Copy Markdown

This PR will fix #3182

Tested Scenarios

# default examples taken from issue:
>>>>> complex(0, float('nan'))
nanj
>>>>> complex(float('nan'), float('nan'))
(nan+nanj)
>>>>> complex(float('nan'), -float('nan'))
(nan+nanj)
>>>>> complex(-float('nan'), float('nan'))
(nan+nanj)
# some random complex numbers to also check it out manually
>>>>> 10j
10j
>>>>> 1-10j
(1-10j)
>>>>> complex(10, float('10'))
(10+10j)
>>>>> complex(-10, float('10'))
(-10+10j)
complex(10, float('nan'))
(10+nanj)
>>>>> complex(float('nan'), 10)
(nan+10j)
>>>>> complex(float('nan'), 1)
(nan+1j)

I am really new to Rust so feel free to give any constructive criticism 🥊

fn repr(&self) -> String {
let Complex64 { re, im } = self.value;
if re == 0.0 {
let re_part = if re.is_nan() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, here's a another idea. We can re-use float formatting to get the job done (and get long float values for the real and imag parts to print out in scientific notation).

Inside float_ops we have to_string that takes an f64 and returns it nicely formatted (it also includes handling of the NaN). The main issue is the sign we add, if its a nan for imag we must always prefix with a "+" (granted that a real part exists).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a really great suggestion, sorry I did not check float_ops before 😞
Changing this right now.

@mdegis

mdegis commented Oct 2, 2021

Copy link
Copy Markdown
Author

Inside float_ops we have to_string that takes an f64 and returns it nicely formatted (it also includes handling of the NaN). The main issue is the sign we add, if its a nan for imag we must always prefix with a "+" (granted that a real part exists).

So I've made the change you suggested as:

if re == 0.0 {
    format!("{}j", float_ops::to_string(im))
} else if im.is_nan() {
    format!("({}+nanj)", float_ops::to_string(re))
} else {
    format!("({}{:+}j)", float_ops::to_string(re), float_ops::to_string(im))
}

It covered examples given in the issue:

>>>>> complex(0, float('nan'))
nanj
>>>>> complex(float('nan'), float('nan'))
(nan+nanj)
>>>>> complex(float('nan'), -float('nan'))
(nan+nanj)
>>>>> complex(-float('nan'), float('nan'))
(nan+nanj)

However, when I tested it with some random complex numbers, it does not go as planned:

>>>>> 10j
10.0j
>>>>> 10j
10.0j
>>>>> 1-10j
(1.0-10.0j)
>>>>> complex(10, float('10'))
(10.010.0j)
>>>>> complex(-10, float('10'))
(-10.010.0j)

I know that {:+} does not work because given value is not numerical, it can be fixed with checking if the im part is greater than 0 and add plus sign but it does not feel right.

Second to that, float_ops::to_string serialize it as float always. For example; in current -messy- implementation 10j will be 10j but new one will print it as 10.0j.

Right now, I am little bit confused how to proceed (maybe I misunderstood something?) . Open to any suggestion 😿

@DimitrisJim

Copy link
Copy Markdown
Member

You can forward the f64 to floats_ops::to_string only if it has a fractional part (f64::fract) that is != 0.0.

@youknowone

Copy link
Copy Markdown
Member

@mdegis are you working on this issue? otherwise we will merge #3228

@mdegis

mdegis commented Oct 7, 2021

Copy link
Copy Markdown
Author

I've done some work on this issue but using to_lowercase() method is much simple approach than forwarding the f64 to floats_ops::to_string only if it has a fractional part (f64::fract) that is != 0.0.

I do not want to steal any ones work so, in the name of simplicity #3228 can be merged.

@youknowone

Copy link
Copy Markdown
Member

Thank you for considerate response. Do you want another issue to work on?

@mdegis

mdegis commented Oct 7, 2021

Copy link
Copy Markdown
Author

Thank you for considerate response. Do you want another issue to work on?

No, thank you.

@mdegis mdegis closed this Oct 7, 2021
@mdegis
mdegis deleted the fix/complex_repr branch October 7, 2021 14:39
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.

Fix complex.__repr__ handling of nan.

3 participants