[Steven D'Aprano] > I'm looking for some way to get the next floating point number after any > particular float. ... > According to the IEEE standard, there should be a routine like next(x,y) > which returns the next float starting from x in the direction of y. > > Unless I have missed something, Python doesn't appear to give an interface > to the C library's next float function. I assume that most C floating > point libraries will have such a function.
While the C99 standard defines such a function (several, actually), the C89 standard does not, so Python can't rely on one being available. In general, Python's `math` module exposes only standard C89 libm functions, plus a few extras it can reliably and portably build itself on top of those. It does not expose platform-specific libm functions. You can argue with that policy, but not successfully unless you take over maintenance of mathmodule.c <0.5 wink>. > So I came up with a pure Python implementation, and hoped that somebody > who had experience with numerical programming in Python would comment. If you're happy with what you wrote, who needs comments ;-) Here's a careful, "kinda portable" implementation in C: http://www.netlib.org/toms/722 If you ignore all the end cases (NaNs, infinities, signaling underflow and overflow, ...), the heart of it is just adding/subtracting 1 to/from the 64-bit double representation, viewing it as an 8-byte integer. That works fine for the IEEE-754 float representations (but does not work for all float representations). I've used this simple routine based on that observation, which ignores all endcases, and only works if both input and result are >= 0: """ from struct import pack, unpack def next(x, direction=+1): bits = unpack(">Q", pack(">d", x))[0] return unpack(">d", pack(">Q", bits + direction))[0] """ For example, >>> next(0) # smallest denorm > 0 4.9406564584124654e-324 >>> next(_, -1) # should really signal underflow 0.0 >>> next(1) 1.0000000000000002 >>> next(1, -1) 0.99999999999999989 >>> next(1e100) 1.0000000000000002e+100 >>> next(1e100, -1) 9.9999999999999982e+099 -- http://mail.python.org/mailman/listinfo/python-list