Pine Script中小数数值比较异常问题咨询
Pine Script极小数值比较异常问题解析
问题现象
测试代码
log.info("I => bar_idx: {0, number} high: {1, number, #.############} low: {2, number, #.############} high_1: {3, number, #.############} low_1: {4, number, #.############}", bar_idx, high_v, low_v, high1_v, low1_v) log.warning(" {0, number, #.############} < {1, number, #.############}: {2} {3, number, #.############} > {4, number, #.############}: {5}", high_v, high1_v, high_v < high1_v, low_v, low1_v, low_v > low1_v) log.warning(" {0, number, #.############} > {1, number, #.############}: {2} {3, number, #.############} < {4, number, #.############}: {5}", high_v, high1_v, high_v > high1_v, low_v, low1_v, low_v < low1_v) log.warning(" {0, number, #.############} == {1, number, #.############}: {2} {3, number, #.############} == {4, number, #.############}: {5}", high_v, high1_v, high_v == high1_v, low_v, low1_v, low_v == low1_v)
日志输出
[2023-04-24T00:00:00.000-00:00]: I => bar_idx: 1 high: 0.000000000028 low: 0.000000000007 high_1: 0.000000000019 low_1: 0.000000000006 [2023-04-24T00:00:00.000-00:00]: 0.000000000028 < 0.000000000019: false 0.000000000007 > 0.000000000006: false [2023-04-24T00:00:00.000-00:00]: 0.000000000028 > 0.000000000019: false 0.000000000007 < 0.000000000006: false [2023-04-24T00:00:00.000-00:00]: 0.000000000028 == 0.000000000019: true 0.000000000007 == 0.000000000006: true
核心疑问:
- 明明十进制数值有差异,
0.000000000007 > 0.000000000006、0.000000000028 > 0.000000000019却返回false 0.000000000028 == 0.000000000019、0.000000000007 == 0.000000000006返回true
原因分析
这是浮点数精度限制导致的必然结果:
Pine Script使用IEEE 754标准的64位双精度浮点数存储数值,这种格式对接近0的极小数值的表示精度有限。当数值小到一定阈值时,两个不同的十进制小数会被映射到同一个二进制浮点数存储值——日志里显示的是格式化后的十进制结果,但内存中实际存储的数值已经丢失了区分这些极小差异的精度,因此直接比较时会出现不符合直觉的结果。
规避方法
针对这类极小数值的比较,有三种可靠的解决思路:
1. 数值放大为整数比较
将所有涉及比较的数值乘以足够大的倍数,转换为整数后再进行比较,彻底规避浮点数精度损失:
// 按数值量级放大1e12倍,转为整数 high_v_int = math.round(high_v * 1e12) high1_v_int = math.round(high1_v * 1e12) // 基于整数的精确比较 log.warning("high_v > high1_v: {}", high_v_int > high1_v_int) log.warning("high_v == high1_v: {}", high_v_int == high1_v_int)
2. 自定义容差(Epsilon)比较
设置一个极小的容差值,通过判断两数差值的绝对值是否小于容差,替代直接的相等比较;大于/小于比较时也结合容差逻辑:
// 根据数值量级定义容差,可灵活调整 epsilon = 1e-15 // 自定义相等判断 is_equal = math.abs(high_v - high1_v) < epsilon // 自定义大于判断:确保差值超过容差 is_greater = (high_v > high1_v) and (math.abs(high_v - high1_v) >= epsilon) log.warning("high_v == high1_v (容差版): {}", is_equal) log.warning("high_v > high1_v (容差版): {}", is_greater)
3. 使用内置函数简化判断
如果仅需判断数值是否接近,可直接使用Pine Script内置的ta.isclose()函数,它已封装了容差比较逻辑:
// 自定义容差百分比(示例为0.0000001%),判断两数是否接近 is_close = ta.isclose(high_v, high1_v, 0.0000001) log.warning("high_v 与 high1_v 接近: {}", is_close)
内容的提问来源于stack exchange,提问作者Rostfrei
相关产品推荐
相关产品推荐

