如何用numpy或math实现函数取整到等比数列(2,4,8…)的最近项?
实现寻找等比数列最近项的函数
给定的等比数列是2的正整数次幂序列:2¹, 2², 2³, ...,核心思路是通过对数运算定位输入值对应的幂次区间,再比较相邻两项的距离确定最近项。
使用math模块实现
import math def func(x): if x <= 0: raise ValueError("输入必须是正实数") log_val = math.log(x, 2) # 判断是否为2的整数次幂 if log_val.is_integer(): return 2 ** int(log_val) # 定位输入值所在的幂次区间 n = math.floor(log_val) lower = 2 ** n upper = 2 ** (n + 1) # 计算到区间两端的距离 d_lower = x - lower d_upper = upper - x # 距离相等时返回较小项,否则返回更近的项 return lower if d_lower <= d_upper else upper
测试验证:
func(3)返回2(与2、4距离相等,取较小值)func(20)返回16(20到16的距离小于到32的距离)func(128)返回128(本身是数列中的项)
使用numpy模块实现
如果需要处理批量输入,numpy版本更高效,同时支持单个数值和数组输入:
import numpy as np def func_np(x): if isinstance(x, (int, float)) and x <= 0: raise ValueError("输入必须是正实数") log_val = np.log2(x) # 判断是否为2的整数次幂(兼容浮点精度误差) is_power_of_two = np.isclose(log_val, np.round(log_val)) # 处理单个数值输入 if isinstance(x, (int, float)): if is_power_of_two: return int(2 ** np.round(log_val)) n = np.floor(log_val).astype(int) lower = 2 ** n upper = 2 ** (n + 1) d_lower = x - lower d_upper = upper - x return lower if d_lower <= d_upper else upper # 处理数组输入 results = np.empty_like(x) n = np.floor(log_val).astype(int) lower = 2 ** n upper = 2 ** (n + 1) d_lower = x - lower d_upper = upper - x # 按距离规则填充结果 results[d_lower <= d_upper] = lower[d_lower <= d_upper] results[d_lower > d_upper] = upper[d_lower > d_upper] # 替换本身是2的幂次的项 results[is_power_of_two] = 2 ** np.round(log_val[is_power_of_two]) return results
例如调用 func_np(np.array([3,20,128])),会返回 array([ 2, 16, 128])。
内容的提问来源于stack exchange,提问作者Timothy
相关产品推荐
相关产品推荐

