Log(2 ** 62,2).is_integer()返回false。有什么想法吗?

时间:2014-08-24 19:24:55

标签: python python-2.7

我正在尝试打印

>>> math.log(2 ** 62,2).is_integer()

返回

False

类似地,

>>> math.log(2**62,2).is_integer()
False
>>> math.log(2**26,2).is_integer()
True
>>> math.log(2**28,2).is_integer()
True
>>> math.log(2**31,2).is_integer()
False
>>> math.log(2**32,2).is_integer()
True
>>> math.log(2**33,2).is_integer()
True
>>> math.log(2**31,2).is_integer()
False
>>> math.log(2**30,2).is_integer()
True
>>> math.log(2**63,2).is_integer()
True
>>> math.log(2**64,2).is_integer()
True
>>> math.log(2**62,2).is_integer()
False

结果非常模糊,各种整数的变化不同。

任何想法为什么?

修改

Sylvain在这里提到

>>> math.log(2**62,2) 

返回

62.00000000000001

为什么会这样?请问有人可以解释一下吗?

FYI - >对于范围(100)中的许多数字,它确实返回正确的整数,如下所示

>>> for i in range(100):
        print 'math.log(2**'+str(i)+',2)' + ' --> ' + str(float(math.log(2**i,2))) + ' Is Integer? --> ' + str(math.log(2**i,2).is_integer())

math.log(2**0,2) --> 0.0 Is Integer? --> True
math.log(2**1,2) --> 1.0 Is Integer? --> True
math.log(2**2,2) --> 2.0 Is Integer? --> True
math.log(2**3,2) --> 3.0 Is Integer? --> True
math.log(2**4,2) --> 4.0 Is Integer? --> True
math.log(2**5,2) --> 5.0 Is Integer? --> True
math.log(2**6,2) --> 6.0 Is Integer? --> True
math.log(2**7,2) --> 7.0 Is Integer? --> True
math.log(2**8,2) --> 8.0 Is Integer? --> True
math.log(2**9,2) --> 9.0 Is Integer? --> True
math.log(2**10,2) --> 10.0 Is Integer? --> True
math.log(2**11,2) --> 11.0 Is Integer? --> True
math.log(2**12,2) --> 12.0 Is Integer? --> True
math.log(2**13,2) --> 13.0 Is Integer? --> True
math.log(2**14,2) --> 14.0 Is Integer? --> True
math.log(2**15,2) --> 15.0 Is Integer? --> True
math.log(2**16,2) --> 16.0 Is Integer? --> True
math.log(2**17,2) --> 17.0 Is Integer? --> True
math.log(2**18,2) --> 18.0 Is Integer? --> True
math.log(2**19,2) --> 19.0 Is Integer? --> True
math.log(2**20,2) --> 20.0 Is Integer? --> True
math.log(2**21,2) --> 21.0 Is Integer? --> True
math.log(2**22,2) --> 22.0 Is Integer? --> True
math.log(2**23,2) --> 23.0 Is Integer? --> True
math.log(2**24,2) --> 24.0 Is Integer? --> True
math.log(2**25,2) --> 25.0 Is Integer? --> True
math.log(2**26,2) --> 26.0 Is Integer? --> True
math.log(2**27,2) --> 27.0 Is Integer? --> True
math.log(2**28,2) --> 28.0 Is Integer? --> True
math.log(2**29,2) --> 29.0 Is Integer? --> False
math.log(2**30,2) --> 30.0 Is Integer? --> True
math.log(2**31,2) --> 31.0 Is Integer? --> False
math.log(2**32,2) --> 32.0 Is Integer? --> True
math.log(2**33,2) --> 33.0 Is Integer? --> True
math.log(2**34,2) --> 34.0 Is Integer? --> True
math.log(2**35,2) --> 35.0 Is Integer? --> True
math.log(2**36,2) --> 36.0 Is Integer? --> True
math.log(2**37,2) --> 37.0 Is Integer? --> True
math.log(2**38,2) --> 38.0 Is Integer? --> True
math.log(2**39,2) --> 39.0 Is Integer? --> False
math.log(2**40,2) --> 40.0 Is Integer? --> True
math.log(2**41,2) --> 41.0 Is Integer? --> True
math.log(2**42,2) --> 42.0 Is Integer? --> True
math.log(2**43,2) --> 43.0 Is Integer? --> True
math.log(2**44,2) --> 44.0 Is Integer? --> True
math.log(2**45,2) --> 45.0 Is Integer? --> True
math.log(2**46,2) --> 46.0 Is Integer? --> True
math.log(2**47,2) --> 47.0 Is Integer? --> False
math.log(2**48,2) --> 48.0 Is Integer? --> True
math.log(2**49,2) --> 49.0 Is Integer? --> True
math.log(2**50,2) --> 50.0 Is Integer? --> True
math.log(2**51,2) --> 51.0 Is Integer? --> False
math.log(2**52,2) --> 52.0 Is Integer? --> True
math.log(2**53,2) --> 53.0 Is Integer? --> True
math.log(2**54,2) --> 54.0 Is Integer? --> True
math.log(2**55,2) --> 55.0 Is Integer? --> False
math.log(2**56,2) --> 56.0 Is Integer? --> True
math.log(2**57,2) --> 57.0 Is Integer? --> True
math.log(2**58,2) --> 58.0 Is Integer? --> False
math.log(2**59,2) --> 59.0 Is Integer? --> False
math.log(2**60,2) --> 60.0 Is Integer? --> True
math.log(2**61,2) --> 61.0 Is Integer? --> True
math.log(2**62,2) --> 62.0 Is Integer? --> False
math.log(2**63,2) --> 63.0 Is Integer? --> True
math.log(2**64,2) --> 64.0 Is Integer? --> True
math.log(2**65,2) --> 65.0 Is Integer? --> True
math.log(2**66,2) --> 66.0 Is Integer? --> True
math.log(2**67,2) --> 67.0 Is Integer? --> True
math.log(2**68,2) --> 68.0 Is Integer? --> True
math.log(2**69,2) --> 69.0 Is Integer? --> True
math.log(2**70,2) --> 70.0 Is Integer? --> True
math.log(2**71,2) --> 71.0 Is Integer? --> True
math.log(2**72,2) --> 72.0 Is Integer? --> True
math.log(2**73,2) --> 73.0 Is Integer? --> True
math.log(2**74,2) --> 74.0 Is Integer? --> True
math.log(2**75,2) --> 75.0 Is Integer? --> True
math.log(2**76,2) --> 76.0 Is Integer? --> True
math.log(2**77,2) --> 77.0 Is Integer? --> True
math.log(2**78,2) --> 78.0 Is Integer? --> False
math.log(2**79,2) --> 79.0 Is Integer? --> True
math.log(2**80,2) --> 80.0 Is Integer? --> True
math.log(2**81,2) --> 81.0 Is Integer? --> True
math.log(2**82,2) --> 82.0 Is Integer? --> True
math.log(2**83,2) --> 83.0 Is Integer? --> True
math.log(2**84,2) --> 84.0 Is Integer? --> True
math.log(2**85,2) --> 85.0 Is Integer? --> True
math.log(2**86,2) --> 86.0 Is Integer? --> True
math.log(2**87,2) --> 87.0 Is Integer? --> True
math.log(2**88,2) --> 88.0 Is Integer? --> True
math.log(2**89,2) --> 89.0 Is Integer? --> True
math.log(2**90,2) --> 90.0 Is Integer? --> True
math.log(2**91,2) --> 91.0 Is Integer? --> True
math.log(2**92,2) --> 92.0 Is Integer? --> True
math.log(2**93,2) --> 93.0 Is Integer? --> False
math.log(2**94,2) --> 94.0 Is Integer? --> False
math.log(2**95,2) --> 95.0 Is Integer? --> False
math.log(2**96,2) --> 96.0 Is Integer? --> True
math.log(2**97,2) --> 97.0 Is Integer? --> True
math.log(2**98,2) --> 98.0 Is Integer? --> True
math.log(2**99,2) --> 99.0 Is Integer? --> True

2 个答案:

答案 0 :(得分:4)

所有结果均为floatsis_integer不检查结果的类型是否为整数。它检查浮点值是否为整数。

舍入错误可能导致is_integer不可靠:

>>> math.log(2**26,2)
26.0
>>> math.log(2**62,2)
62.00000000000001

由于上面的操作是通过使用自然对数来执行的,我猜测这里的舍入误差是由log(2)
除法引入的({{1}是} math.log(x,2))。

答案 1 :(得分:3)

对于大于2 ** 53的数字,解释是双精度(64位)浮点数不能表示大于该精度的整数。这些情况下的对数函数已经接收到近似输入,当然它无法提供准确的输出。

编辑:2的幂可以准确表示...问题是对于不是2的幂且大于2 ** 53的整数。

该日志未能对2 ** 31进行精确计算确实有点令人惊讶,因为今天PC显然最常见的硬件都有浮点单元中基数2计算对数的指令。

然而,Python代码是用C语言编写的,C库并没有在Python支持的所有构建环境中提供base 2库函数的对数。这意味着所有的计算都是从自然对数和基数的变化中完成的;这解释了即使是像2 ** 31这样的小值也不准确。对于通用math.log函数,即使编译器提供对它的支持,对案例库的特殊处理也不是2。

Python 3 math模块包含log2函数,并且用于计算基数2中的对数的代码使用log2原语(如果平台上存在该原语)。确实在Linux中math.log2(2**31)是准确的,而math.log(2**31, 2)则不然。 我已经读过微软C ++数学库没有实现log2的地方,因此我不希望它在Windows中运行的Python 3实现中是准确的(Python代码是用Visual C ++编译。

编辑:似乎这不再是真的,或者从来都不是真的。即使在Python 3的Windows版本上,math.log2也是准确的。