浮点范围搜索异常:已知ratio与X组合无法被Python代码捕获
问题分析与解决方案
核心问题
问题根源在于浮点数累加的精度误差和低效的双重循环逻辑:
- 浮点数(如
float类型)累加0.000001时,多次循环后会出现微小偏差,导致X或ratio无法精确命中目标值21.278393和2.252316。 - 双重循环遍历所有
X和ratio组合,不仅效率极低,还放大了浮点误差的影响。
修正方案
方案1:用整数计数替代浮点数累加
通过整数步数计算实际的X和ratio值,避免浮点数累加带来的误差:
from tqdm import tqdm start_ratio = 2.199164 end_ratio = 2.277869 target = 47.92567055 start_X = 21.072100 end_X = 21.373130 step = 0.000001 EPSILON = 1e-6 found = [] # 计算总步数,用整数避免浮点误差 total_X_steps = int((end_X - start_X) / step) + 1 for i in tqdm(range(total_X_steps), desc="Scanning X values"): current_X = start_X + i * step # 直接计算所需的ratio,避免遍历所有ratio required_ratio = target / current_X # 检查ratio是否在范围内,且乘积误差符合要求 if (start_ratio <= required_ratio <= end_ratio) and abs(required_ratio * current_X - target) < EPSILON: # 保留6位小数,匹配目标值的精度 rounded_ratio = round(required_ratio, 6) rounded_X = round(current_X, 6) print(f"[FOUND] ratio={rounded_ratio:.6f}, X={rounded_X:.6f}, value={rounded_ratio*rounded_X:.6f}") with open("./data/phase_2.txt", "a") as file: file.write(f"[FOUND] ratio={rounded_ratio:.6f}, X={rounded_X:.6f}, value={rounded_ratio*rounded_X:.6f}\n") found.append((rounded_ratio, rounded_X, rounded_ratio*rounded_X)) print(f"Matches found: {len(found)}")
方案2:使用Decimal确保高精度计算
如果必须用Decimal,需确保所有数值、步长和运算都基于Decimal类型,避免混合float:
from tqdm import tqdm from decimal import Decimal, getcontext # 设置足够高的精度 getcontext().prec = 12 start_ratio = Decimal('2.199164') end_ratio = Decimal('2.277869') target = Decimal('47.92567055') start_X = Decimal('21.072100') end_X = Decimal('21.373130') step = Decimal('0.000001') EPSILON = Decimal('1e-6') found = [] total_X_steps = int((end_X - start_X) / step) + 1 for i in tqdm(range(total_X_steps), desc="Scanning X values"): current_X = start_X + i * step required_ratio = target / current_X if (start_ratio <= required_ratio <= end_ratio) and abs(required_ratio * current_X - target) < EPSILON: rounded_ratio = round(required_ratio, 6) rounded_X = round(current_X, 6) print(f"[FOUND] ratio={rounded_ratio}, X={rounded_X}, value={rounded_ratio*rounded_X}") with open("./data/phase_2.txt", "a") as file: file.write(f"[FOUND] ratio={rounded_ratio}, X={rounded_X}, value={rounded_ratio*rounded_X}\n") found.append((rounded_ratio, rounded_X, rounded_ratio*rounded_X)) print(f"Matches found: {len(found)}")
关键改进点
- 避免双重循环:通过
ratio = target / X直接计算所需ratio,减少不必要的遍历,同时消除ratio遍历的误差。 - 整数计数计算值:用
start_X + i * step代替X += step,彻底避免浮点数累加的精度漂移。 - 匹配精度控制:对计算出的ratio和X保留6位小数,确保与目标组合的精度一致。
内容的提问来源于stack exchange,提问作者Gor Barseghyan
相关产品推荐
相关产品推荐

