You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用math.floor出现舍入问题:币安加密货币订单数量计算异常

问题产生原因

该问题本质是二进制浮点数精度误差导致的。Python 中默认的 float 类型为双精度64位二进制浮点数,类似0.1、0.01这类十进制有限小数,在二进制存储中属于无限循环小数,经过多次乘除运算后会出现微小的精度偏移。比如理论计算结果本应为步长的整数倍,实际运算后可能得到类似 0.1200000000001 或者 0.1199999999999 的值,最终输出出现多余的尾数位,不符合币安接口的步长校验规则。

修复方案

推荐以下三种落地方式,可根据实际场景选择:

  • 方案1:使用decimal模块做十进制精确运算(最稳妥,适配所有场景)
    完全规避二进制浮点的精度问题,和币安返回的十进制步长、价格规则完全匹配:
import math
from decimal import Decimal, ROUND_FLOOR

def calculate_order_sizes():
    # 下单美元金额用字符串初始化,避免初始化时就出现精度损失
    order_amount = Decimal("100")
    for coin_dict in coin_list:
        price = Decimal(str(coin_dict['price']))
        step = Decimal(str(coin_dict['step']))
        # 计算理论购币数量后向下取整到步长的整数倍
        raw_size = order_amount / price
        valid_size = (raw_size / step).to_integral_value(rounding=ROUND_FLOOR) * step
        # 可按需转成float或者直接转字符串传给下单接口
        coin_dict['order'] = float(valid_size)
  • 方案2:整数放大运算
    将所有数值按步长的小数位数放大为整数计算,全程用整数运算规避浮点误差:
import math

def get_decimal_places(num):
    # 计算步长对应的小数位数
    s = str(num).rstrip('0')
    return len(s.split('.')[1]) if '.' in s else 0

def calculate_order_sizes():
    for coin_dict in coin_list:
        step = coin_dict['step']
        decimal_places = get_decimal_places(step)
        scale = 10 ** decimal_places
        # 全部放大到整数维度做运算
        raw_size_scaled = (100 / coin_dict['price']) * scale
        valid_size_scaled = math.floor(raw_size_scaled / (step * scale)) * (step * scale)
        coin_dict['order'] = valid_size_scaled / scale
  • 方案3:原有逻辑基础上增加小数位截断
    如果不想修改原有核心计算逻辑,可以在输出前按步长的小数位数做截断,消除多余尾数位:
import math

def get_decimal_places(num):
    s = str(num).rstrip('0')
    return len(s.split('.')[1]) if '.' in s else 0

def calculate_order_sizes():
    for coin_dict in coin_list:
        raw_order = coin_dict['step'] * math.floor((100/coin_dict['price'])/coin_dict['step'])
        decimal_places = get_decimal_places(coin_dict['step'])
        # 保留和步长一致的小数位数,消除精度误差尾数位
        coin_dict['order'] = round(raw_order, decimal_places)

注:币安下单接口要求订单数量的小数位不能超过步长对应的小数位数,建议最终传给接口的参数可以转成对应小数位数的字符串格式,进一步避免传输过程中的精度问题。

内容的提问来源于stack exchange,提问作者Christina Norwood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 21:45:05