判断一个数是分数还是n的最佳方法

2024-06-01 01:26:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我想区分 2.02和实际的小数,如2.4。最好的办法是什么?目前我正在做:

def is_fractional(num):
    if not str(num).replace('.','').isdigit(): return
    return float(num) != int(num)

>>> is_fractional(2)
False
>>> is_fractional(2.1)
True
>>> is_fractional(2.0)
False
>>> is_fractional('a')
>>>

Tags: falsereturnifisdefnotfloatnum
3条回答

该操作是内置的:

>>> 5.0.is_integer()
True
>>> 5.00000001.is_integer()
False
>>> 4.9999999.is_integer()
False

文档是here。你知道吗

附录

初始解决方案只适用于float。下面是一个更完整的答案,包括测试:

from decimal import Decimal

def is_integer(x):
    if isinstance(x, int):
        return True
    elif isinstance(x, float):
        return x.is_integer()
    elif isinstance(x, Decimal):
        return x.as_integer_ratio()[1] == 1
    return False

good = [
    0, 
    0.0, 
    3, 
    -9999999999999999999999, 
    -2.0000000000000,
    Decimal("3.000000"),
    Decimal("-9")
]
bad = [
    -9.99999999999999,
    "dogs",
    Decimal("-4.00000000000000000000000000000000001"),
    Decimal("0.99999999999999999999999999999999999")
]

for x in good:
    assert is_integer(x)
for x in bad:
    assert not is_integer(x)
print("All tests passed")

为什么不检查整数的截断值和精确值之间的差值是否不为零?你知道吗

is_frac = lambda x: int(x)-x != 0

如果您的一些数字是decimal.Decimal,则它们可能存在范围问题,无法转换为float,或者删除实际存在的小数部分,具体取决于它们的精度:

>>> import decimal
>>> x = decimal.Decimal('1.00000000000000000000000000000000000001')
>>> str(x)
'1.00000000000000000000000000000000000001'
>>> float(x).is_integer()
True

>>> y = decimal.Decimal('1e5000')
>>> str(y)
'1E+5000'
>>> float(y)
inf

str方法通常会起作用(如上图所示的模块化问题案例),因此您可以坚持这样做,但最好尝试使用is_integer并在失败时使用回退:

try:
   return x.is_integer()
except AttributeError:
   pass

(正如其他人所注意到的,如果这些类型是允许的,那么您也需要在这里检查intlong,因为它们在定义上是整数,但缺少is_integer属性)。你知道吗

在这一点上,值得考虑所有其他的答案,但这里有一个具体的答案十进制。十进制经办人:

# optional: special case decimal.Decimal here
try:
    as_tuple = x.as_tuple()
    trailing0s = len(list(itertools.takewhile(lambda i: i == 0, reversed(as_tuple[1]))))
    return as_tuple[2] + trailing0s < 0
except (AttributeError, IndexError): # no as_tuple, or not 3 elements long, etc
    pass

相关问题 更多 >