在python中检查float是否等效于整数值

在python中检查float是否等效于整数值,python,floating-point,Python,Floating Point,在Python3中,我检查给定的值是否是三角形的,也就是说,对于某个正整数n,它可以表示为n(n+1)/2 我可以写下: import math def is_triangular1(x): num=(1/2) * (math.sqrt(8*x+1)-1 ) return int(num)==num 还是我需要这样做 epsilon = 0.000000000001 def is_triangular2(x): num=(1/2) * (math.sqrt(8*x+1)

在Python3中,我检查给定的值是否是三角形的,也就是说,对于某个正整数n,它可以表示为n(n+1)/2

我可以写下:

import math
def is_triangular1(x):
    num=(1/2) * (math.sqrt(8*x+1)-1 )
    return int(num)==num
还是我需要这样做

epsilon = 0.000000000001
def is_triangular2(x):
    num=(1/2) * (math.sqrt(8*x+1)-1 )
    return abs(int(num) - num)<epsilon
epsilon=0.000000000001
def是_三角形2(x):
num=(1/2)*(数学sqrt(8*x+1)-1)

return abs(int(num)-num)Python仍然使用与C相同的浮点表示法和操作,因此第二种方法是正确的。

您可能希望使用后者。在Python3编程中,以下示例是最准确的比较方法

def equal_float(a, b):
    #return abs(a - b) <= sys.float_info.epsilon
    return abs(a - b) <= chosen_value #see edit below for more info
def相等浮点数(a,b):

#return abs(a-b)Python确实有一个
Decimal
类(in),您可以使用它来避免浮点数的不精确性。

我认为模块Decimal是您需要的

您可以将数字四舍五入到例如14位或更少:

 >>> round(4.999999999999997, 14)
 5.0

注:双精度约为15位小数

您的两种实现都有问题。实际上,您可能会得到类似于
4.9999999999999 7
的结果,因此使用
int()
不是一个选项

我会选择一种完全不同的方法:首先假设你的数字是三角形的,然后计算出在这种情况下,
n
。在第一步中,您可以进行大量的四舍五入,因为只有当数字实际上是三角形时,才需要得到正确的结果。接下来,为该
n
计算
n*(n+1)/2
,并将结果与
x
进行比较。现在,您正在比较两个整数,因此没有不精确之处

n
的计算可以通过扩展简化

(1/2) * (math.sqrt(8*x+1)-1) = math.sqrt(2 * x + 0.25) - 0.5
并利用这一点

round(y - 0.5) = int(y)
对于正
y

def is_triangular(x):
    n = int(math.sqrt(2 * x))
    return x == n * (n + 1) / 2

在后台,Python的float类型是C-double

最可靠的方法是获取最接近num的整数,然后测试该整数是否满足您所追求的属性:

import math
def is_triangular1(x):
    num = (1/2) * (math.sqrt(8*x+1)-1 )
    inum = int(round(num))
    return inum*(inum+1) == 2*x  # This line uses only integer arithmetic

很难与标准争论

在C99和POSIX中,将浮点四舍五入为整数的标准是由重要的概念定义的,即四舍五入的方向和特定于语言环境的四舍五入约定

假设约定为,这与Python中的C99约定相同:

#!/usr/bin/python

import math

infinity = math.ldexp(1.0, 1023) * 2

def nearbyint(x): 
   """returns the nearest int as the C99 standard would"""

   # handle NaN
   if x!=x:
       return x      

   if x >= infinity:
       return infinity

   if x <= -infinity:
       return -infinity

   if x==0.0:
       return x

   return math.floor(x + 0.5)
#/usr/bin/python
输入数学
无穷大=数学ldexp(1.01023)*2
def nearbyint(x):
“”“返回与C99标准最接近的整数”“”
#处理楠
如果x=x:
返回x
如果x>=无穷大:
返回无穷远

如果xfloat可以精确地表示其范围内的所有整数-只有在关心点后的位时,浮点相等才是棘手的。因此,只要公式中的所有计算都返回您感兴趣的情况下的整数,int(num)=num是完全安全的

所以,我们需要证明,对于任何三角形数,你所做的每一项数学运算都可以用整数运算完成(任何非整数的运算都意味着x不是三角形):

首先,我们可以假设x必须是一个整数——这在“三角数”的定义中是必需的

在这种情况下,8*x+1也将是整数,因为整数在+和*下闭合

sqrt()返回float;但是如果x是三角形,那么平方根将是一个整数——也就是说,同样精确地表示

因此,对于函数中应该返回true的所有x,int(num)=num将为true,因此istriangular1将始终有效。问题注释中提到的唯一症结是,Python 2默认情况下以与C-int/int=>int相同的方式进行整数除法,如果结果不能精确表示为int,则截断。因此,1/2==0。在Python3中,或者通过使用

from __future__ import division
在代码顶部附近。

python float类型中有一个函数:

>>> float(1.0).is_integer()
True
>>> float(1.001).is_integer()
False
>>> 

考虑使用NumPy,他们会照顾引擎盖下的一切

将numpy作为np导入


result\u bool=np.isclose(float1,float2)

我知道您询问的是浮点和整数,但您可能会发现以下Q有用。两个函数可能返回相同的值,但出于某种原因,它们对我尝试过的所有数字都返回True。@Jochen,您使用的是Python3吗?在Python2中
1/2==0
所以
num
总是
0
@gnibler:哦,对了,我应该更仔细地读一读,不要为这个问题而工作:
5-4.999999999997对了一半。不要使用
sys.float\u info.epsilon
。使用一个特定于问题域的值。@s-Lott为什么不使用sys.float\u info.epsilon?@Sunny88:进行代数运算。浮点值的表示错误可能大于sys.float\u info.epsilon
epsilon=0.000000000001
更可能是正确的,因为它取决于您的问题域中的某些内容,而不是浮点表示法的任意属性。@Dan:edit仅部分修复了该问题。您需要根据一些epsilon检查相对错误,而这个epsilon不一定是
sys.float\u info.epsilon
。也许您想阅读.round(y-0.5)=int(y)似乎并不总是正确的:在Python 3中,round(1-0.5)==0,但int(1)==1@Sunny:有趣--
round()
的行为在Python3.x中发生了变化。但是因为我们只想对非常接近整数的数字进行四舍五入,所以我们不必担心小数部分在这里正好是
0.5
。正如我之前所说的,我们可以非常容忍舍入,因为我们只需要在数字实际上是三角形的情况下正确地进行舍入。这就是为什么省略
0.25
也是可以的。您可以列出所有三角形数
((x*x+x)/2表示count()中的x)
,然后测试函数是否为这些值提供True,为其他值提供False。。。确实如此,因为Python可以将所有数字转换为整数。为什么inum=int(round(num))而不仅仅是inum