Skip to content

BUG: allow for precision > 17 in longdouble repr test #8656

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 2 commits into from
Feb 22, 2017

Conversation

matthew-brett
Copy link
Contributor

@matthew-brett matthew-brett commented Feb 21, 2017

Precision of repr print unconditionally set to 20, for longdoubles != double. Allow for this
in repr round-trip test for longdouble.

Closes gh-7940.

# We will only see eps in repr if within printing precision.
# Printing precision defined as 17 in scalartypes.c.src
expected = 1.0 if LD_INFO.precision > 17 else o
assert_equal(np.longdouble(repr(o)), expected,
"repr was %s" % repr(o))
Copy link
Member

Choose a reason for hiding this comment

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

Wait, isn't the bug here that the repr is capped at a precision of 17 when it shouldn't be?

Copy link
Member

Choose a reason for hiding this comment

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

Also, scalartypes.c.src seems to cap it at 20, not 17, unless longdouble and double are the same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you're right, I was just looking at that code. Can correct the comment and constant, but the question is, do we really want - for example - 31 digits of precision for np.longdouble (that's what double double gives, on PPC64). If so, we'd have to adapt the scalartypes.c.src code to detect the different types of longdouble.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's desirable that repr roundtrips properly, and I don't think that changing the test to allow the failure here is the right solution. So yes, on PPC64 I think that it should print 31 digits for repr - there's always str for the sane-length output.

Obviously it's not desirable use 31 digits on platforms that don't support it, but as a quick fix, I think that 20 should be become 33 (precision +2 used elsewhere).

Adapting scalartypes.c.src to choose more intelligently is an obvious next step.

@matthew-brett
Copy link
Contributor Author

Pointing to now-hidden discussion : #8656 (comment)

The question is - how much do we care about the round-trippiness of repr for longdouble? If we do care about that then:

a) we'd get 33 digits of repr precision on PPC64, and 36 on SPARC (real float128) and
b) we'd have to re-implement the longdouble type detection in scalartype.c.src - which might be easy, but I don't know how to do it.

@eric-wieser
Copy link
Member

Side-note: make a PR with just the LD_INFO changes and I'll merge it

@matthew-brett
Copy link
Contributor Author

My vote would be to give up on struct repr roundtrip correctness, at least for now, because:

  • we haven't previously had this for np.longdouble not in (float64, float80) and;
  • 33 digits will be a lot of text for values in an array and;
  • changing the repr for longdouble might disturb some doctests and;
  • it appears from the top of numpy/core/tests/test_longdouble.py that some platforms lack (an accurate?) strtold_l and therefore repr roundtrip cannot work for these, and;
  • this workaround already seems better than the failing test.

@eric-wieser
Copy link
Member

33 digits will be a lot of text for values in an array

As far as I remember, ndarray.__repr__ does not directly invoke self.dtype.type.__repr__, but instead uses the (independent) print settings. So I don't think this argument holds

@matthew-brett
Copy link
Contributor Author

OK - happy to withdraw that part of the argument.

@eric-wieser
Copy link
Member

I'm not convinced the workaround is correct though. I think that if the precision is too high, the test should be skipped altogether, rather than verifying that it does not roundtrip

@matthew-brett
Copy link
Contributor Author

How about:

def test_repr_roundtrip():
    o = 1 + LD_INFO.eps
    # We will only see eps in repr if within printing precision.
    repr_precision = len(repr(np.longdouble(0.1))) - 2
    if LD_INFO.precision >= repr_precision:
        assert_equal(np.longdouble(repr(o)), o, "repr was %s" % repr(o))

Then, if we want to increase the repr precision later, the test will be triggered automatically.

@eric-wieser
Copy link
Member

That sounds pretty good to me, although I might still be tempted to mark it as a skipped test somehow rather than it no-opping

@matthew-brett
Copy link
Contributor Author

OK - I pushed up a version where we skip the test when there isn't enough repr precision.

a = np.array([o, o, o])
assert_equal(a[1], o)


# Conversions string -> long double


@dec.skipif(LD_INFO.precision >= len(repr(np.longdouble(0.1))) - 2,
Copy link
Member

@eric-wieser eric-wieser Feb 22, 2017

Choose a reason for hiding this comment

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

Probably better doing:

repr_precision = len(repr(np.longdouble(0.1)))
# +2 comes from <the right lines in scalar_types>
@dec.skipif(LD_INFO.precision + 2 >= repr_precision)

Precision of repr set to 22 when longdouble != double, but this isn't
enough for double double (precision 33) or float128 (precision 34).  If
repr precision is not high enough to show eps value, skip the test.

Closes numpygh-7940.
test_longdouble had two tests called test_fromstring_foreign, so the
second was overwriting the first.  Rename the first so test gets run.
@matthew-brett
Copy link
Contributor Author

Made that change. Also (sorry) - I re-enabled an unrelated test that was being overwritten.

@matthew-brett
Copy link
Contributor Author

test_longdouble tests pass from this branch on SPARC and PPC64el.

@eric-wieser
Copy link
Member

Looks good to me. I doubt anyone is actually going to be able to confirm those test results on SPARC or PPC64el, so I'll take your word for it

@eric-wieser eric-wieser merged commit 58d7c8c into numpy:master Feb 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants