<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="Generator" content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang="EN-US" link="blue" vlink="purple"><div><div style="font-family: Calibri,sans-serif; font-size: 11pt;">These days, the subset of C99 supported by MSVC is "most" of it, so feel free to start off by assuming the best, at least for new features (the version we use for 2.7 obviously is not improving).<br><br>Cheers,<br>Steve<br><br>Top-posted from my Windows Phone</div></div><div dir="ltr"><hr><span style="font-family: Calibri,sans-serif; font-size: 11pt; font-weight: bold;">From: </span><span style="font-family: Calibri,sans-serif; font-size: 11pt;"><a href="mailto:tritium-list@sdamon.com">tritium-list@sdamon.com</a></span><br><span style="font-family: Calibri,sans-serif; font-size: 11pt; font-weight: bold;">Sent: </span><span style="font-family: Calibri,sans-serif; font-size: 11pt;">‎2/‎4/‎2017 3:53</span><br><span style="font-family: Calibri,sans-serif; font-size: 11pt; font-weight: bold;">To: </span><span style="font-family: Calibri,sans-serif; font-size: 11pt;"><a href="mailto:python-ideas@python.org">python-ideas@python.org</a></span><br><span style="font-family: Calibri,sans-serif; font-size: 11pt; font-weight: bold;">Subject: </span><span style="font-family: Calibri,sans-serif; font-size: 11pt;">Re: [Python-ideas] math.nextafter</span><br><br></div><div class="WordSection1"><p class="MsoNormal"><span style='font-family: "Calibri",sans-serif; font-size: 11pt;'>The presence of the function in C99’s math.h isn’t strictly useful unless it is also in the MSVC math.h.  MSVC only supports a subset of C99<o:p></o:p></span></p><p class="MsoNormal"><span style='font-family: "Calibri",sans-serif; font-size: 11pt;'><o:p> </o:p></span></p><div style="border-width: medium medium medium 1.5pt; border-style: none none none solid; border-color: currentColor currentColor currentColor blue; padding: 0in 0in 0in 4pt; border-image: none;"><div><div style="border-width: 1pt medium medium; border-style: solid none none; border-color: rgb(225, 225, 225) currentColor currentColor; padding: 3pt 0in 0in; border-image: none;"><p class="MsoNormal"><b><span style='font-family: "Calibri",sans-serif; font-size: 11pt;'>From:</span></b><span style='font-family: "Calibri",sans-serif; font-size: 11pt;'> Python-ideas [mailto:python-ideas-bounces+tritium-list=sdamon.com@python.org] <b>On Behalf Of </b>Juraj Sukop<br><b>Sent:</b> Saturday, February 4, 2017 6:31 AM<br><b>To:</b> python-ideas@python.org<br><b>Subject:</b> [Python-ideas] math.nextafter<o:p></o:p></span></p></div></div><p class="MsoNormal"><o:p> </o:p></p><div><div><p class="MsoNormal">Hello!<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">Function `nextafter(x, y)` returns the next representable value of `x` in the direction of `y`, and if `x` equals to `y`, `y` is returned. [1]<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">It is useful for incrementing/decrementing floating-point number by the smallest amount possible or for testing if two numbers are closest to each other without being the same.<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">The following snippet written by Mark Dickinson emulates the functionality in pure Python [2]:<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">    import math<o:p></o:p></p></div><div><p class="MsoNormal">    import struct<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">    def next_up(x):<o:p></o:p></p></div><div><p class="MsoNormal">        # NaNs and positive infinity map to themselves.<o:p></o:p></p></div><div><p class="MsoNormal">        if math.isnan(x) or (math.isinf(x) and x > 0):<o:p></o:p></p></div><div><p class="MsoNormal">            return x<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">        # 0.0 and -0.0 both map to the smallest +ve float.<o:p></o:p></p></div><div><p class="MsoNormal">        if x == 0.0:<o:p></o:p></p></div><div><p class="MsoNormal">            x = 0.0<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">        n = struct.unpack('<q', struct.pack('<d', x))[0]<o:p></o:p></p></div><div><p class="MsoNormal">        if n >= 0:<o:p></o:p></p></div><div><p class="MsoNormal">            n += 1<o:p></o:p></p></div><div><p class="MsoNormal">        else:<o:p></o:p></p></div><div><p class="MsoNormal">            n -= 1<o:p></o:p></p></div><div><p class="MsoNormal">        return struct.unpack('<d', struct.pack('<q', n))[0]<o:p></o:p></p></div><div><p class="MsoNormal">    <o:p></o:p></p></div><div><p class="MsoNormal">    def next_down(x):<o:p></o:p></p></div><div><p class="MsoNormal">        return -next_up(-x)<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">    def next_after(x, y):<o:p></o:p></p></div><div><p class="MsoNormal">        # If either argument is a NaN, return that argument.<o:p></o:p></p></div><div><p class="MsoNormal">        # This matches the implementation in decimal.Decimal<o:p></o:p></p></div><div><p class="MsoNormal">        if math.isnan(x):<o:p></o:p></p></div><div><p class="MsoNormal">            return x<o:p></o:p></p></div><div><p class="MsoNormal">        if math.isnan(y):<o:p></o:p></p></div><div><p class="MsoNormal">            return y<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">        if y == x:<o:p></o:p></p></div><div><p class="MsoNormal">            return y<o:p></o:p></p></div><div><p class="MsoNormal">        elif y > x:<o:p></o:p></p></div><div><p class="MsoNormal">            return next_up(x)<o:p></o:p></p></div><div><p class="MsoNormal">        else:<o:p></o:p></p></div><div><p class="MsoNormal">            return next_down(x)<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">Other implementations can be found at [3], [4] or [5], for example.<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">It would be useful to have `math.nextafter` function available in standard library, it also is provided by C99 <math.h>, and is similar in spirit to `math.copysign` or `math.isclose`.<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">As to why to include it by default when the above snippet works just fine, a C implementation is likely to be much faster than using `struct.pack` and `struct.unpack`.<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">Thank you for considering this proposal and any feedback is greatly welcomed!<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">Juraj Sukop<o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div><div><p class="MsoNormal">[1] <a href="http://en.cppreference.com/w/c/numeric/math/nextafter">http://en.cppreference.com/w/c/numeric/math/nextafter</a><o:p></o:p></p></div><div><p class="MsoNormal">[2] <a href="http://stackoverflow.com/a/10426033">http://stackoverflow.com/a/10426033</a><o:p></o:p></p></div><div><p class="MsoNormal">[3] <a href="http://git.musl-libc.org/cgit/musl/tree/src/math/nextafter.c">http://git.musl-libc.org/cgit/musl/tree/src/math/nextafter.c</a><o:p></o:p></p></div><div><p class="MsoNormal">[4] <a href="https://github.com/android/platform_bionic/blob/master/libm/upstream-freebsd/lib/msun/src/s_nextafter.c">https://github.com/android/platform_bionic/blob/master/libm/upstream-freebsd/lib/msun/src/s_nextafter.c</a><o:p></o:p></p></div><div><p class="MsoNormal">[5] <a href="https://github.com/golang/go/blob/master/src/math/nextafter.go">https://github.com/golang/go/blob/master/src/math/nextafter.go</a><o:p></o:p></p></div><div><p class="MsoNormal"><o:p> </o:p></p></div></div></div></div></body></html>