Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Next float?

Reply
Thread Tools

Next float?

 
 
Steven D'Aprano
Guest
Posts: n/a
 
      11-22-2007
Is there a simple, elegant way in Python to get the next float from a
given one? By "next float", I mean given a float x, I want the smallest
float larger than x.

Bonus points if I can go in either direction (i.e. the "previous float"
as well as the next).

Note to maths pedants: I am aware that there is no "next real number",
but floats are not reals.


--
Steven
 
Reply With Quote
 
 
 
 
Alex Holkner
Guest
Posts: n/a
 
      11-22-2007
On Nov 22, 2007 2:04 PM, Steven D'Aprano
<(E-Mail Removed)> wrote:
> Is there a simple, elegant way in Python to get the next float from a
> given one? By "next float", I mean given a float x, I want the smallest
> float larger than x.
>
> Bonus points if I can go in either direction (i.e. the "previous float"
> as well as the next).


Not so elegant, but you could use ctypes to manipulate the bits
(assumes machine uses IEEE 754 doubles for Python floats, I'm not sure
if that's guaranteed on esoteric platforms):

import ctypes

def inc_float(f):
# Get an int64 pointer to the float data
fv = ctypes.c_double(f)
pfv = ctypes.pointer(fv)
piv = ctypes.cast(pfv, ctypes.POINTER(ctypes.c_uint64))

# Check for NaN or infinity, return unchanged
v = piv.contents.value
if not ~(v & (11 << 52)): # exponent is all 1's
return f

if v == 1 << 63: # -0, treat as +0
v = 1
elif v & (1 << 63): # negative
v -= 1
else: # positive or +0
v += 1

# Set int pointer and return changed float
piv.contents.value = v
return fv.value

def dec_float(f):
# Get an int64 pointer to the float data
fv = ctypes.c_double(f)
pfv = ctypes.pointer(fv)
piv = ctypes.cast(pfv, ctypes.POINTER(ctypes.c_uint64))

# Check for NaN or infinity, return unchanged
v = piv.contents.value
if not ~(v & (11 << 52)): # exponent is all 1's
return f

if v == 0: # +0, treat as -0
v = (1 << 63) | 1
elif v & (1 << 63): # negative
v += 1
else: # positive
v -= 1

# Set int pointer and return changed float
piv.contents.value = v
return fv.value
 
Reply With Quote
 
 
 
 
Mark T
Guest
Posts: n/a
 
      11-22-2007

"Steven D'Aprano" <(E-Mail Removed)> wrote in message
news(E-Mail Removed) ce.com.au...
> Is there a simple, elegant way in Python to get the next float from a
> given one? By "next float", I mean given a float x, I want the smallest
> float larger than x.
>
> Bonus points if I can go in either direction (i.e. the "previous float"
> as well as the next).
>
> Note to maths pedants: I am aware that there is no "next real number",
> but floats are not reals.
>
>
> --
> Steven


Here's some functions to get the binary representation of a float. Then
just manipulate the bits (an exercise for the reader):

import struct

def f2b(f):
return struct.unpack('I',struct.pack('f',f))[0]

def b2f(b):
return struct.unpack('f',struct.pack('I',b))[0]

>>> f2b(1.0)

1065353216
>>> hex(f2b(1.0))

'0x3f800000'
>>> b2f(0x3f800000)

1.0
>>> b2f(0x3f800001)

1.0000001192092896
>>> b2f(0x3f7fffff)

0.99999994039535522

-Mark

 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      11-22-2007
Steven D'Aprano <(E-Mail Removed)> writes:
> Is there a simple, elegant way in Python to get the next float from a
> given one? By "next float", I mean given a float x, I want the smallest
> float larger than x.


I think you have to do it by bit twiddling. But something like bisection
search could come pretty close, for well-behaved values of x:

def nextfloat(x):
dx = (x, x/2.0)
while x+dx[1] != x:
dx = (dx[1], dx[1]/2.0)
return dx[0]+x
 
Reply With Quote
 
Robert Kern
Guest
Posts: n/a
 
      11-22-2007
Steven D'Aprano wrote:
> Is there a simple, elegant way in Python to get the next float from a
> given one? By "next float", I mean given a float x, I want the smallest
> float larger than x.


Courtesy of Tim Peters:

http://mail.python.org/pipermail/pyt...st/099152.html

> Bonus points if I can go in either direction (i.e. the "previous float"
> as well as the next).


Left as an exercise for the reader.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

 
Reply With Quote
 
Robert Kern
Guest
Posts: n/a
 
      11-22-2007
Steven D'Aprano wrote:
> Is there a simple, elegant way in Python to get the next float from a
> given one? By "next float", I mean given a float x, I want the smallest
> float larger than x.


Heh:

http://mail.python.org/pipermail/pyt...er/357771.html

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      11-22-2007
On Thu, 22 Nov 2007 00:44:34 -0600, Robert Kern wrote:

> Steven D'Aprano wrote:
>> Is there a simple, elegant way in Python to get the next float from a
>> given one? By "next float", I mean given a float x, I want the smallest
>> float larger than x.

>
> Heh:
>
> http://mail.python.org/pipermail/pyt...er/357771.html


Damn, I don't remember writing that!

:-/



--
Steven.
 
Reply With Quote
 
Hendrik van Rooyen
Guest
Posts: n/a
 
      11-22-2007
"Steven D'Aprano" <steve..IS.cybersource.com.au> wrote:


> Damn, I don't remember writing that!


It is caused by drinking too much Alzheimer's Light.

: - )

- Hendrik

 
Reply With Quote
 
Fredrik Johansson
Guest
Posts: n/a
 
      11-22-2007
On Nov 22, 2007 4:04 AM, Steven D'Aprano
<(E-Mail Removed)> wrote:
> Is there a simple, elegant way in Python to get the next float from a
> given one? By "next float", I mean given a float x, I want the smallest
> float larger than x.
>
> Bonus points if I can go in either direction (i.e. the "previous float"
> as well as the next).
>
> Note to maths pedants: I am aware that there is no "next real number",
> but floats are not reals.
> --
> Steven


You could use the library functions for floating-point math in mpmath
(http://code.google.com/p/mpmath/), which support directed rounding.
Load a floating-point number, add a tiny number and round in the
wanted direction, then convert back to a Python float:

>>> from mpmath.lib import *
>>> eps = (1, -2000, 1) # 2**-2000, smaller than any finite

positive IEEE 754 double
>>> a = from_float(1.0, 53, ROUND_HALF_EVEN) # note: exact
>>> to_float(fadd(a, eps, 53, ROUND_UP))

1.0000000000000002
>>> to_float(fsub(a, eps, 53, ROUND_DOWN))

0.99999999999999989

This currently probably doesn't work if the numbers are subnormal, however.

Fredrik
 
Reply With Quote
 
Mark Dickinson
Guest
Posts: n/a
 
      11-22-2007
On Nov 21, 11:48 pm, "Mark T" <(E-Mail Removed)> wrote:
> Here's some functions to get the binary representation of a float. Then
> just manipulate the bits (an exercise for the reader):
>
> import struct
>
> def f2b(f):
> return struct.unpack('I',struct.pack('f',f))[0]
>
> def b2f(b):
> return struct.unpack('f',struct.pack('I',b))[0]
>
> >>> f2b(1.0)

> 1065353216
> >>> hex(f2b(1.0))

> '0x3f800000'
> >>> b2f(0x3f800000)

> 1.0
> >>> b2f(0x3f800001)

> 1.0000001192092896
> >>> b2f(0x3f7fffff)

>
> 0.99999994039535522


And it's worth noting that thanks to the way the floating-point format
is designed, the 'bit-twiddling' is actually just a matter of adding
or subtracting one from the integer representation above. This works
all the way from zero, through subnormals, up to and including
infinities.

Mark (but not the same Mark)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Reading of file by next of map file and by next of file descriptor. =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki C++ 1 07-10-2007 02:46 AM
Perl 5.00404 - Label not found for "next " , next() function Liora Perl Misc 5 01-12-2007 03:36 AM
Next (the other next) Gen "DVD" storage Alan Browne Digital Photography 13 05-31-2005 05:53 PM
CurrentElement->next = CurrentElement->next->next (UNDEFINED?) Deniz Bahar C Programming 2 03-09-2005 12:45 AM
Skipping content in Array within loop and go to the next (of NEXT function) Tad McClellan Perl Misc 3 05-13-2004 10:14 PM



Advertisments