Se podía ver cómo se implementan Decimal.next_plus()
/Decimal.next_minus()
:
>>> from decimal import Decimal as D
>>> d = D.from_float(123456.789)
>>> d
Decimal('123456.789')
>>> d.next_plus()
Decimal('123456.789')
>>> d.next_minus()
Decimal('123456.789')
>>> d.next_toward(D('-inf'))
Decimal('123456.789')
Asegúrese de que decimal context tiene valores que necesitará:
>>> from decimal import getcontext
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
capitals=1, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
Alternativas:
Call C99 nextafter()
usando ctypes
:
>>> import ctypes
>>> nextafter = ctypes.CDLL(None).nextafter
>>> nextafter.argtypes = ctypes.c_double, ctypes.c_double
>>> nextafter.restype = ctypes.c_double
>>> nextafter(4, float('+inf'))
4.000000000000001
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
Usando numpy
:
>>> import numpy
>>> numpy.nextafter(4, float('+inf'))
4.0000000000000009
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
pesar de las diferentes repr()
, el resultado es el mismo.
si ignoramos casos extremos a continuación, una solución frexp/ldexp simple a partir de @S.Lott answer obras:
>>> import math, sys
>>> m, e = math.frexp(4.0)
>>> math.ldexp(2 * m + sys.float_info.epsilon, e - 1)
4.000000000000001
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
pure Python next_after(x, y)
implementation by @Mark Dickinson que tenga en cuenta los casos límite. El resultado es el mismo en este caso. Se preguntó
La misma pregunta aquí: http://bytes.com/topic/python/answers/739926-next-float, con buenas respuestas ... – Benjamin