检查float是否为整数:is_integer()与modulo 1

时间:2018-03-13 09:10:19

标签: python

我已经看过许多问题,询问如何检查浮点数是否为整数。大多数答案似乎建议使用is_integer()

(1.0).is_integer()
(1.55).is_integer()

我偶尔也会看到math.floor()被使用:

import math
1.0 == math.floor(1.0)
1.55 == math.floor(1.55)

我想知道为什么% 1很少被使用或推荐?

1.0 % 1 == 0
1.55 % 1 == 0

为此目的使用modulo是否有问题?是否存在这种无法捕获的边缘情况?真正大数字的性能问题?

如果% 1是一个很好的选择,那么我也想知道为什么is_integer()被引入标准库?

似乎%更灵活。例如,通常使用% 2检查数字是奇数/偶数,还是使用% n来检查某些内容是否是n的倍数。鉴于这种灵活性,为什么要引入一个新方法(is_integer)来做同样的事情,或者使用math.floor,这两个方法都需要知道/记住它们存在并知道如何使用它们?我知道math.floor除了整数检查之外还有其他用途,但仍然......

2 个答案:

答案 0 :(得分:1)

一个明显的原因是:可读性

如果名为is_integer()的函数返回True,那么您所测试的内容就很明显了。

但是,使用模数解决方案时,必须仔细考虑该过程才能看到它实际上是在测试浮点数是否为整数。如果你将模数形式包装在一个具有明显名称的函数中,例如simon_says_its_an_integer(),我认为它一样好(除了不必要地引入已有的函数)。

答案 1 :(得分:0)

所有这些都是有效的。 math.floor选项要求特定值与floor函数的结果完全匹配。如果要将其封装在通用方法中,这不是很方便。所以它归结为第一个和第三个选项。两者都有效,并将完成这项工作。所以关键的区别很简单 - 性能:

from timeit import Timer

def with_isint(num):
    return num.is_integer()
def with_mod(num):
    return num % 1 == 0

Timer(lambda: with_isint(10.0)).timeit(number=10000000)
#output: 2.0617980659008026
Timer(lambda: with_mod(10.0)).timeit(number=10000000)
#output: 2.6560597440693527

当然,这是一个简单的操作,因此您需要进行大量调用才能看到相当大的差异,正如您在示例中所看到的那样。