python十进制-检查是否为整数

3pvhb19x  于 2023-02-07  发布在  Python
关注(0)|答案(9)|浏览(151)

我使用Python中的Decimal库,并使用format(value, 'f')打印值,其中value是Decimal。我得到10.00000的数字,它反映了小数的精度。我知道float支持is_integer,但似乎缺少类似的小数API。我想知道是否有办法解决这个问题。

zynd9foi

zynd9foi1#

你可以使用模运算来检查是否有一个非整数余数:

>>> from decimal import Decimal
>>> Decimal('3.14') % 1 == 0
False
>>> Decimal('3') % 1 == 0
True
>>> Decimal('3.0') % 1 == 0
True
vh0rcniy

vh0rcniy2#

请尝试math.floor(val) == valval == int(val)

vcirk6k6

vcirk6k63#

在Python 3.6中,Decimal有一个方法as_integer_ratio()
as_integer_ratio()返回(分子,分母)元组。如果分母为1,则值为整数。

>>> from decimal import Decimal
>>> Decimal("123.456").as_integer_ratio()[1] == 1
False
>>> Decimal("123.000").as_integer_ratio()[1] == 1
True
jum4pzuy

jum4pzuy4#

数学上的解决方法是将十进制数转换为整数,然后测试它是否与您的数字相等。
由于Decimal可以具有任意精度,因此不应将其转换为intfloat
幸运的是Decimal类有一个to_integral_value可以帮你转换,你可以采用这样的解决方案:

def is_integer(d):
    return d == d.to_integral_value()

示例:

from decimal import Decimal

d_int = Decimal(3)
assert is_integer(d_int)

d_float = Decimal(3.1415)
assert not is_integer(d_float)
cqoc49vn

cqoc49vn5#

Decimal确实有一个“隐藏”的方法,叫做_isinteger(),它的工作原理有点像float的is_integer()方法:

>>> Decimal(1)._isinteger()
True
>>> Decimal(1.1)._isinteger()
Traceback (most recent call last):
  File "C:\Program Files (x86)\Wing IDE 4.1\src\debug\tserver\_sandbox.py", line 1, in <module>
    # Used internally for debug sandbox under external interpreter
  File "C:\Python26\Lib\decimal.py", line 649, in __new__
    "First convert the float to a string")
TypeError: Cannot convert float to Decimal.  First convert the float to a string

正如你所看到的,你必须捕捉一个异常,或者,你可以在把值传递给Decimal之前,使用你提到的float方法或者isinstance对值进行测试。

ljsrvy3e

ljsrvy3e6#

您可以在Decimal对象上调用as_tuple()以获取符号数字序列指数,它们共同定义Decimal值。
如果一个规格化Decimal的指数为非负,那么你的值就没有小数部分,也就是说,它是一个整数,所以你可以很容易地检查这一点:

def is_integer(dec):
    """True if the given Decimal value is an integer, False otherwise."""
    return dec.normalize().as_tuple()[2] >= 0

试试看:
x一个一个一个一个x一个一个二个x

dkqlctbz

dkqlctbz7#

根据上面所说的,我使用了:

>>> not 2.5 % 1
False
>>> not 1.0 % 1
True
>>> not 14.000001 % 1
False
>>> not 2.00000000 % 1
True

所以你可以使用下面的一个程序:

not value % 1

它将为您提供所需的布尔值。

7uhlpewt

7uhlpewt8#

Decimal类有一个函数to_integral_exact,它将十进制转换为整数,并且如果有任何非零数字被丢弃,也会发出信号。https://docs.python.org/3/library/decimal.html#decimal.Decimal.to_integral_exact
使用这些信息,我们也可以实现浮点数的is_integer用于十进制:

import decimal
def is_integer(value: decimal.Decimal) -> bool:
   is_it = True
   context = decimal.getcontext()
   context.clear_flags()
   exact = value.to_integral_exact()
   if context.flags[decimal.Inexact]:
     is_it = False
   context.clear_flags()
   return is_it

使用上述函数:

# tested on Python 3.9
>>> is_integer(decimal.Decimal("0.23"))
False
>>> is_integer(decimal.Decimal("5.0000"))
True
>>> is_integer(decimal.Decimal("5.0001"))
False
6g8kf2rb

6g8kf2rb9#

另一种方法是使用quantize()方法,该方法通常用于舍入小数:

>>> from decimal import Decimal
>>> for d in (Decimal('2.72'), Decimal('3.14'), Decimal('3.0'), Decimal('3')):
...     d == d.quantize(Decimal('1'))
... 
False
False
True
True

相关问题