[issue39288] Add math.nextafter(a, b)

2020-01-12 Thread STINNER Victor


STINNER Victor  added the comment:

I created bpo-39310 to propose to add math.ulp(x).

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-12 Thread STINNER Victor


STINNER Victor  added the comment:


New changeset 54cfbb2feee1f7328c3d6799ec3734b00824b555 by Victor Stinner in 
branch 'master':
bpo-39288: Add examples to math.nextafter() documentation (GH-17962)
https://github.com/python/cpython/commit/54cfbb2feee1f7328c3d6799ec3734b00824b555


--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-12 Thread Mark Dickinson


Mark Dickinson  added the comment:

> I suggest "next_after" instead of "nextafter".

"nextafter" gives us consistency with C, with NumPy and with other compound 
names in the math module ("isnan", "isclose", "copysign"). My own brain doesn't 
perceive either of "nextafter" or "next_after" as more readable than the other.

What's the argument for "next_after"?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-12 Thread STINNER Victor


Change by STINNER Victor :


--
pull_requests: +17371
pull_request: https://github.com/python/cpython/pull/17962

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

I suggest "next_after" instead of "nextafter".

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread STINNER Victor


STINNER Victor  added the comment:

I chose to make y mandatory in nextafter(x, y). Implement your own flavor if 
nextUp(x) if you want to omit y. I prefer to make y explicit, becauseit has 
been said in this discussion that "nextafter" name is ambiguous.

Thanks all for the constructive discussion. I merged my PR reviewed by Mark. 
Enjoy IEEE 754 and have fun with rounding!

--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread STINNER Victor


STINNER Victor  added the comment:


New changeset 100fafcf20e8fc67cd8ef512074f9c0a253cb427 by Victor Stinner in 
branch 'master':
bpo-39288: Add math.nextafter(x, y) (GH-17937)
https://github.com/python/cpython/commit/100fafcf20e8fc67cd8ef512074f9c0a253cb427


--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread Mark Dickinson


Mark Dickinson  added the comment:

> Do you mean nextafter(x, y=inf, /): toward positive infinity by default?

Yes; I believe that was what Steven was suggesting in the last part of 
msg359779. I don't have strong feelings either way.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread Mark Dickinson


Mark Dickinson  added the comment:

[Steven]

> I know Wikipedia isn't a primary source, but it says IEEE 754 recommends 
> nextafter(x, y).

Um. Then it sounds as though Wikipedia is out of date. Which page was this on?

IEEE 754-1985 did recommend nextafter, but only in Annex A, which is not 
strictly part of the standard. ("This Appendix is not a part of ANSI/IEEE Std 
754-1985, IEEE Standard for Binary Floating-Point Arithmetic [...]")

IEEE 754-2008 (section 5.3.1) added nextUp and nextDown as required operations, 
and the text for those operations is word-for-word identical in the current 
IEEE 754-2019, save for "sNaNs" being spelled out as "signaling NaNs".

> My understanding of IEEE-754 is that the functionality is required, not the 
> specific API. That is, it's not required to have literally two functions 
> called "nextUp" and "nextDown", so long as you can get the next larger and 
> next smaller float.

Agreed. It's not really spelled out in the standard exactly what "conformance" 
would mean, but I agree that providing nextafter should be sufficient if we 
want to claim that Python supports the nextUp and nextDown operations.

Not that Python makes any claim to conform with IEEE 754 anyway, but I think 
it's still a useful standard to consider when we're choosing what to do in the 
math module.

I guess if we *wanted* to claim strict conformance with IEEE 754 (which we 
don't, right now), we'd probably also want to add a note in the docs explaining 
how nextUp and nextDown are represented in terms of nextafter. But that seems a 
bit redundant to me.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread STINNER Victor

STINNER Victor  added the comment:

Mark:
> Making the second argument optional sounds reasonable to me, but doesn't 
> necessarily have to happen in the existing PR; we can always add that option 
> later.

Do you mean nextafter(x, y=inf, /): toward positive infinity by default? I 
prefer to keep the second parameter mandatory, to make the direction more 
explicit. As Tim showed, it's easy to implement nextUp() on top of 
nextafter().


> "nextafter" is fine with me.

Good :-) It seems like everybody agrees on nextafter().


> it would be good to make sure that we have tests for the behaviour matching 
> the spec, particularly with respect to signed zeros: the first clause here 
> implies nextafter(0.0, -0.0) is -0.0, while nextafter(-0.0, 0.0) is 0.0.

I had a test for math.nextafter(+0.0, -0.0). I added a test for 
math.nextafter(-0.0, +0.0).


> I'd also recommend adding tests for nextafter(smallest_normal, 0.0), 
> nextafter(largest_normal, inf), nextafter(inf, 0),

Done.


> and the like.

Feel free to suggest more tests on the PR.


> The C standard isn't 100% clear on what nextafter(-0.0, inf) should be

I added a test for it, for positive and negative zeros.


> But IEEE 754 is explicit that nextUp(±0) is the smallest positive subnormal

That's what I get.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread Mark Dickinson

Mark Dickinson  added the comment:

"nextafter" is fine with me. I just wanted to make sure that we'd considered 
the options, and weren't choosing nextafter simply because it's the easiest 
thing to implement.

[Victor]

> It mentions for example "If x== y, y (of the type x) shall be returned" and 
> "If x or y is NaN, a NaN shall be returned". It's good to know that it's 
> specified ;-)

Agreed; it would be good to make sure that we have tests for the behaviour 
matching the spec, particularly with respect to signed zeros: the first clause 
here implies nextafter(0.0, -0.0) is -0.0, while nextafter(-0.0, 0.0) is 0.0. 
I'd also recommend adding tests for nextafter(smallest_normal, 0.0), 
nextafter(largest_normal, inf), nextafter(inf, 0), and the like. 

The C standard isn't 100% clear on what nextafter(-0.0, inf) should be: it 
could be argued that the "next" representable float after -0.0 in the direction 
of infinity is 0.0. But IEEE 754 is explicit that nextUp(±0) is the smallest 
positive subnormal, and we should have a test for that, too.

Making the second argument optional sounds reasonable to me, but doesn't 
necessarily have to happen in the existing PR; we can always add that option 
later.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread STINNER Victor


STINNER Victor  added the comment:

Oh, I forgot to also give the nextafer() link to the POSIX standard:
https://pubs.opengroup.org/onlinepubs/009695399/functions/nextafter.html

It mentions for example "If x== y, y (of the type x) shall be returned" and "If 
x or y is NaN, a NaN shall be returned". It's good to know that it's specified 
;-)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-11 Thread STINNER Victor


STINNER Victor  added the comment:

PR 17937 is ready to be reviewed. The tests passed on the regular CIs and 
buildbots: good.

> That last assumes you want -0 and +0 to act differently

It is the case: I wrote an unit test checking exactly that, and it works as 
expected on all platforms (Windows, macOS, Linux, Intel, PPC, etc.).

> `nextafter()` is too widely implemented to fight against, despite the sucky 
> name ;-)

nexttoward name is less ambiguous, but as you all said: "nextafter" name is way 
more popular. Honestly, it's not that hard to infer that the function can go 
"up" or "down" because it has a second parameter. If it's not obvious enough, 
maybe we can enhance the documentation.

--

About Wikipedia, the following articles are interesting for the ones like me 
who don't fully understand IEEE 754, rounding mode, etc.

* https://en.wikipedia.org/wiki/Unit_in_the_last_place
* https://en.wikipedia.org/wiki/Machine_epsilon
* https://en.wikipedia.org/wiki/IEEE_754

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread Tim Peters


Tim Peters  added the comment:

[Steven]
> I think the second argument should also be optional, so
> that nextafter(x) returns the next representable float.

That's why the name sucks - there are, in general, two adjacent floats, so 
"next" is ambiguous.  I expect you intend that y default to math.inf, which 
would make one-argument `nextafter(x)` a spelling of `nextUp(x)`.  Fine by me!  
That's probably the one I want most often.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread Steven D'Aprano


Steven D'Aprano  added the comment:

I agree, "nextafter" is so widely used it's probably pointless to fight against 
the name :-)

Mark: "IEEE 754, on the other hand, requires instead nextUp and nextDown".

I know Wikipedia isn't a primary source, but it says IEEE 754 recommends 
nextafter(x, y).

My understanding of IEEE-754 is that the functionality is required, not the 
specific API. That is, it's not required to have literally two functions called 
"nextUp" and "nextDown", so long as you can get the next larger and next 
smaller float.

I think the second argument should also be optional, so that nextafter(x) 
returns the next representable float.

--
nosy: +steven.daprano

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread Tim Peters


Tim Peters  added the comment:

No doubt that something along these lines would be useful.

`nextafter()` is too widely implemented to fight against, despite the sucky 
name ;-)

I believe the rest should be straightforward (for those who want them) to do 
with one-liners, so there's not much of a case for building them in.  Or is 
that wrong?  My guesses for correct implementations:

def nextUp(x):
return math.nextafter(x, math.inf)

def nextDown(x):
return math.nextafter(x, -math.inf)

def nextAwayFromZero(x):
return math.nextafter(x, math.copysign(math.inf, x))

That last assumes you want -0 and +0 to act differently; i.e., want

nextAwayFromZero(0.0) == 5e-324
and
nextAwayFromZero(-0.0) == -5e-324

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread STINNER Victor


STINNER Victor  added the comment:

> NumPy has nextafter.

That's why I proposed math.nextafter() name.

Moreover, in the math module, most functions reuse the same names than C 
function names: expm1(), atan2(), erf(), etc.


> IEEE 754, on the other hand, requires instead nextUp and nextDown, which take 
> a single argument and move towards +inf or -inf (respectively).

When I played with bpo-39277, I used nextafter() to try to implement manually a 
conversion from an integer to a float using rounding towards zero. So I prefer 
nextafter() than nextUp()/nextDown(): it gives more features.


> but nextAwayFromZero doesn't match any of these

It seems easy to reimplement it using nextafter(), no?

def nextAwayFromZero(x):
if x < 0:
return math.nextafter(x, -float("inf"))
else:
return math.nextafter(x, +float("inf"))


> Python's Decimal type has a two-argument next_toward method.

It also has next_minus() and next_plus() which don't match "nextUp and 
nextDown" names requires by IEEE 754.

I'm not comfortable with math.next_after() or math.next_toward() name: use a 
different than the libc function name (add an underscore). For me, the math 
module is a thin wrapper to libm function, as the os module is a thin wrapper 
to libc functions.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread Mark Dickinson


Mark Dickinson  added the comment:

I'm not opposed to some form of this by any means, but I fear there's some 
bikeshedding to go through, both on the name and the functionality (one 
function with two arguments, or two functions each taking a single argument?).

C 99 prescribes "nextafter" and "nexttoward" (which is pretty much the same as 
"nextafter" if you don't care about the distinction between float, double and 
long double).

IEEE 754, on the other hand, requires instead nextUp and nextDown, which take a 
single argument and move towards +inf or -inf (respectively).

Python's Decimal type has a two-argument next_toward method.

NumPy has nextafter.

Java provides all three of nextUp, nextDown and nextAfter.

For sure implementing nextafter is easiest, since we can just wrap the C 
version. That doesn't *necessarily* make it the right variant to go for.

(Annoyingly enough, none of these is actually what I tend to want in practice, 
which is "next larger" and "next smaller" functions, or more precisely, 
nextAwayFromZero and nextTowardsZero functions. nextTowardsZero is of course a 
special case of nextafter, but nextAwayFromZero doesn't match any of these.)

--
nosy: +tim.peters

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread STINNER Victor


Change by STINNER Victor :


--
keywords: +patch
pull_requests: +17345
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/17937

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread STINNER Victor


Change by STINNER Victor :


--
keywords: +3.3regression
nosy: +lemburg, mark.dickinson, rhettinger, stutzbach

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39288] Add math.nextafter(a, b)

2020-01-10 Thread STINNER Victor


New submission from STINNER Victor :

Linux manual page of nextafter():
"""
The nextafter() function return the next representable floating-point  value 
following x in the direction of y.  If y is less than x, these functions will 
return the largest representable number less than x.

If x equals y, the functions return y.
"""

I used this function to round an integer towards zero when casting a float to 
an integer in bpo-39277. Example in C:

#include 
#include 
#include 
int main()
{
int64_t int64_max = 9223372036854775807LL;
double d = (double)int64_max;  /* ROUND_HALF_EVEN */
double d2 = nextafter(d, 0.0);
printf("i = %ld\n", int64_max);
printf("d = %.0f\n", d);
printf("d2 = %.0f\n", d2);
printf("d - d2 = %.0f\n", d - d2);
return 0;
}

Output:

i = 9223372036854775807
d = 9223372036854775808
d2 = 9223372036854774784
d - d2 = 1024

The function exists in numpy:

numpy.nextafter(x1, x2, /, out=None, *, where=True, casting='same_kind', 
order='K', dtype=None, subok=True[, signature, extobj]) = 

Return the next floating-point value after x1 towards x2, element-wise.

https://docs.scipy.org/doc/numpy/reference/generated/numpy.nextafter.html


Attached PR adds math.nextafter().

--
components: Library (Lib)
messages: 359731
nosy: vstinner
priority: normal
severity: normal
status: open
title: Add math.nextafter(a, b)
versions: Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com