Python小数modulus取模运算仅部分值生效问题咨询
你提供的代码存在参数名笔误,函数入参声明为number,但遍历范围range()中使用了未定义的pinumber,测试前需要先修正该问题。
问题根因
核心原因是Python默认浮点数的二进制存储精度限制:
- 0.25、0.5、0.75、1.5这类小数均为2的整数次幂的倍数,可以在双精度二进制浮点数格式中被精确存储,因此取模运算的结果可以精确等于0,你的判断条件可以正常触发。
- 1.4这类小数无法被二进制浮点数精确存储,实际保存的是和理论值非常接近的近似值,整数和该近似值做取模运算的结果只会无限接近0,永远不会精确等于0,因此
num % rate == 0的条件永远不成立,没有输出。
修复方案
可以根据使用场景选择以下任意一种方案:
方案1:误差阈值判断(最简便)
不要求精确等于0,改为判断取模结果的绝对值小于一个极小的误差阈值(推荐用1e-9,足够覆盖常规小数计算的精度误差):
def findnum(number, rate): for num in range(number): if abs(num % rate) < 1e-9 and num != 0: print(num)
方案2:整数放大运算(无精度损失)
将所有运算放大为整数运算,彻底规避浮点数精度问题:
def findnum(number, rate): # 计算rate的小数位数,确定放大倍数 rate_str = str(rate) if '.' in rate_str: decimal_len = len(rate_str.split('.')[1]) else: decimal_len = 0 multiply = 10 ** decimal_len # 全部转成整数做整除判断 rate_int = int(rate * multiply) for num in range(number): if (num * multiply) % rate_int == 0 and num != 0: print(num)
方案3:十进制精确运算(适合高精度要求场景)
使用Python标准库decimal做精确的十进制运算,完全避免二进制精度问题:
from decimal import Decimal, getcontext # 设置足够的运算精度 getcontext().prec = 20 def findnum(number, rate): rate_dec = Decimal(str(rate)) for num in range(number): if num != 0 and Decimal(num) % rate_dec == 0: print(num)
内容的提问来源于stack exchange,提问作者MaximumPain
相关产品推荐
相关产品推荐

