Python 2中is_integer()判断64立方根返回False问题求助
问题根源:浮点数精度的微小误差
这个问题其实是二进制浮点数的精度限制在搞鬼!咱们来一步步拆解:
为什么float(64**Fraction(1,3)).is_integer()返回False?
当你用Fraction(1,3)作为指数计算64的立方根时,Python底层会把这个运算转换成近似的浮点数计算:
Fraction(1,3)是精确的分数,但当参与幂运算时,它会被转换为二进制浮点数——而二进制浮点数无法精确表示1/3,只能用一个接近的近似值。- 计算
64 ** 近似1/3时,本质是计算e^( (近似1/3) * ln(64) ),这个过程中会产生微小的精度误差,最终得到的结果可能是3.9999999999999996或者4.000000000000001这类接近4但并非精确4.0的浮点数。 - 当你调用
.is_integer()时,只有精确等于整数的浮点数才会返回True,这种带微小误差的数自然会返回False。
为什么1、8、27能正常返回True?
这些数的立方根是1、2、3这类小整数,它们的对数计算误差刚好被浮点数的表示特性抵消了,最终得到的结果是精确的整数浮点数(比如1.0、2.0),所以.is_integer()能正确识别。但这只是巧合,并非所有完美立方数都能逃过精度问题。
解决方案:用整数运算替代浮点数判断
要彻底避免浮点数精度问题,最好的办法是直接验证一个数是否是某个整数的立方,而不是通过开方转浮点数判断。这里提供两种改进思路:
思路1:遍历可能的整数立方根(高效适合大范围)
先计算出范围[a, b]内最小和最大的整数k,使得k³落在区间内,然后直接生成这些立方数:
from fractions import Fraction counter = 0 a = int(raw_input()) b = int(raw_input()) if 1 <= a <= 10**8 and a <= b <= 10**8: # 估算起始立方根,再调整到正确值 min_k = int(a ** (1/3)) while min_k ** 3 < a: min_k += 1 while (min_k - 1) ** 3 >= a: min_k -= 1 # 估算结束立方根,再调整到正确值 max_k = int(b ** (1/3)) while max_k ** 3 > b: max_k -= 1 while (max_k + 1) ** 3 <= b: max_k += 1 # 统计并输出结果 if max_k >= min_k: counter = max_k - min_k + 1 for k in range(min_k, max_k + 1): print(k ** 3) print(counter) # 测试64的情况 print(4 ** 3 == 64) # 会返回True
思路2:对每个数直接验证(适合小范围)
如果区间范围不大,可以直接对每个数i,判断是否存在整数k使得k³=i:
from fractions import Fraction counter = 0 a = int(raw_input()) b = int(raw_input()) if 1 <= a <= 10**8 and a <= b <= 10**8: for i in range(a, b+1): k = round(i ** (1/3)) # 验证近似值及相邻整数的立方是否等于i,覆盖浮点数估算误差 if k ** 3 == i or (k+1)**3 == i or (k-1)**3 == i: counter +=1 print(i) print(counter)
内容的提问来源于stack exchange,提问作者Willie3838
相关产品推荐
相关产品推荐

