Skip to content
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

bpo-39310: Add math.ulp(x) #17965

Open
wants to merge 4 commits into
base: master
from
Open

bpo-39310: Add math.ulp(x) #17965

wants to merge 4 commits into from

Conversation

@vstinner
Copy link
Member

vstinner commented Jan 12, 2020

Add math.ulp(): return the unit in the last place of x.

https://bugs.python.org/issue39310

Add math.ulp(): return the unit in the last place of x.
@vstinner

This comment has been minimized.

Copy link
Member Author

vstinner commented Jan 12, 2020

The documentation should be enhanced 😊

/*[clinic end generated code: output=f5207867a9384dd4 input=f1004db2d2436ab5]*/
{
if (Py_IS_INFINITY(x) || Py_IS_NAN(x)) {
return x;

This comment has been minimized.

Copy link
@serhiy-storchaka

serhiy-storchaka Jan 12, 2020

Member

It can return negative value.

This comment has been minimized.

Copy link
@vstinner

vstinner Jan 12, 2020

Author Member

Currently, ulp(-INF) returns -INF. Do you prefer ulp() result to always be positive or NaN? So return +INF for ulp(-INF)?

This comment has been minimized.

Copy link
@serhiy-storchaka

serhiy-storchaka Jan 12, 2020

Member

It is the only case when ulp() returns a negative value. It looks surprising. And does not confirm the current documentation.

ulp(nan) also does not confirm the current documentation (because nan <= nan is false). Would not be better to raise an exception?

What different implementations of ulp() does? Is there some specification?

This comment has been minimized.

Copy link
@vstinner

vstinner Jan 12, 2020

Author Member

It is the only case when ulp() returns a negative value.

Ok, I changed this behavior.

ulp(nan) also does not confirm the current documentation (because nan <= nan is false). Would not be better to raise an exception?

Hum, should I just document that ulp(x) returns x if x is not a number?

I dislike the exception idea. Other math functions also return NaN if one argument is NaN. For example, nextafter() returns NaN.

self.assertEqual(math.ulp(0.0),
sys.float_info.min * sys.float_info.epsilon)
self.assertEqual(math.ulp(1.0), sys.float_info.epsilon)
self.assertEqual(math.ulp(2.0 ** 52), 1.0)

This comment has been minimized.

Copy link
@serhiy-storchaka

serhiy-storchaka Jan 12, 2020

Member

Maybe use sys.float_info.radix ** (sys.float_info.mant_dig-1)?

This comment has been minimized.

Copy link
@vstinner

vstinner Jan 12, 2020

Author Member

Tests are hardcoded for binary64. Is it really worth it to make tests generic for other implementations of foat? I'm quite sure that many tests are hardcoded for binary64, I mean, not only test_float.

@vstinner

This comment has been minimized.

Copy link
Member Author

vstinner commented Jan 12, 2020

The documentation should be enhanced blush

Done. I copied the test_math.ulp() docstring.

@tim-one

This comment has been minimized.

Copy link
Member

tim-one commented Jan 12, 2020

I think Java does as well as can be done here:

https://www.geeksforgeeks.org/java-math-ulp-method-examples/

Short course:

  • Return a NaN for a NaN input.
  • Return +inf for an infinite input (regardless of sign).
  • Return the smallest positive representable double for +0 or -0 input.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.