from typing import List, Dict, Any from decimal import Decimal, getcontext, ROUND_DOWN getcontext().prec = 50 # 高精度,避免极端值丢失 def truncate_to_decimals_js(number: float, dots: int) -> float: dec = Decimal(str(number)) # 转成字符串,避免科学计数法 s = format(dec, "f") if "." not in s: return float(s) integer_part, frac_part = s.split(".") truncated_frac = frac_part[:dots] # 截取小数点后 dots 位 truncated_str = f"{integer_part}.{truncated_frac}" if truncated_frac else integer_part return float(truncated_str) def calculate_shares_weight_js(data: List[Dict[str, Any]]) -> Dict[str, float]: user_weights: Dict[str, Dict[str, Any]] = {} for item in data: user = item.get("user") pool_diff = Decimal(str(item.get("pool_diff", 0))) miner_diff = Decimal(str(item.get("miner_diff", 0))) weight = Decimal("0") if pool_diff != 0: weight = miner_diff / pool_diff if user not in user_weights: user_weights[user] = {"totalWeight": Decimal("0"), "data": []} user_weights[user]["totalWeight"] += weight user_weights[user]["data"].append(item) total_weight = sum(u["totalWeight"] for u in user_weights.values()) if total_weight == 0: return {user: 0.0 for user in user_weights.keys()} result: Dict[str, float] = {} for user, v in user_weights.items(): ratio = v["totalWeight"] / total_weight result[user] = truncate_to_decimals_js(float(ratio), 10) return result __all__ = ["calculate_shares_weight_js", "truncate_to_decimals_js"]