Python是否与java.lang.Math.nextUp等价? [英] Does Python have an equivalent to java.lang.Math.nextUp?
问题描述
我有一个Python float
,我想要 float
s,它们是1 ULP 越大越小。
Math.nextUp(x)
和 Math.nextAfter(x,Double.NEGATIVE_INFINITY)
。 有没有办法在Python中做到这一点?我以为自己用 math.frexp
和 math.ldexp
,但据我所知Python没有指定浮点类型的大小。
你可以看看 Decimal.next_plus()
/ Decimal.next_minus()
被执行:
>>>从十进制输入十进制为D
>>> d = D.from_float(123456.78901234567890)
>>> d
十进制('123456.789012345674564130604267120361328125')
>>> d.next_plus()
十进制('123456.7890123456745641306043')
>>> d.next_minus()
十进制('123456.7890123456745641306042')
>>> d.next_toward(D(' - inf'))
十进制('123456.7890123456745641306042')
确保十进制上下文具有您需要的值:
>>> from decimal import getcontext
>>> getcontext()
Context(prec = 28,rounding = ROUND_HALF_EVEN,Emin = -999999999,Emax = 999999999,
capitals = 1,flags = [],陷阱= [InvalidOperation,DivisionByZero,Overflow])
替代方案:
-
调用 C99
nextafter()$使用
ctypes
:> >> import ctypes
>>> nextafter = ctypes.CDLL(无).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)
使用
numpy
:>>> import numpy
>>> numpy.nextafter(4,float('+ inf'))
4.0000000000000009
>>> _.as_integer_ratio()
(4503599627370497,1125899906842624)
尽管不同的
repr()
,结果是一样的。
- 一个href =https://stackoverflow.com/a/6064066/4279> @ S.Lott答案的作品:
>>>导入数学,sys
>>> m,e = math.frexp(4.0)
>>> math.ldexp(2 * m + sys.float_info.epsilon,e - 1)
4.000000000000001
>>> _.as_integer_ratio()
(4503599627370497,1125899906842624)
-
next_after(x,y)执行,考虑到边缘情况。结果在这种情况下是一样的。
I have a Python float
, and I want to have the float
s which are 1 ULP greater and lesser.
In Java, I would do this with Math.nextUp(x)
and Math.nextAfter(x, Double.NEGATIVE_INFINITY)
.
Is there a way to do this in Python? I thought about implementing it myself with math.frexp
and math.ldexp
but as far as I know Python doesn't specify the size of floating point types.
You could look at how Decimal.next_plus()
/Decimal.next_minus()
are implemented:
>>> from decimal import Decimal as D
>>> d = D.from_float(123456.78901234567890)
>>> d
Decimal('123456.789012345674564130604267120361328125')
>>> d.next_plus()
Decimal('123456.7890123456745641306043')
>>> d.next_minus()
Decimal('123456.7890123456745641306042')
>>> d.next_toward(D('-inf'))
Decimal('123456.7890123456745641306042')
Make sure that decimal context has values that you need:
>>> from decimal import getcontext
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
capitals=1, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
Alternatives:
Call C99
nextafter()
usingctypes
:>>> 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)
Using
numpy
:>>> import numpy >>> numpy.nextafter(4, float('+inf')) 4.0000000000000009 >>> _.as_integer_ratio() (4503599627370497, 1125899906842624)
Despite different
repr()
, the result is the same.If we ignore edge cases then a simple frexp/ldexp solution from @S.Lott answer works:
>>> 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 that takes into account edge cases. The result is the same in this case.
这篇关于Python是否与java.lang.Math.nextUp等价?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!