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

如何正确使用FixedU128获取JSON中的0.5价格值?

链下Worker中用lite-json获取浮点数值的正确转换方法

问题场景

我在链下Worker中通过lite-json解析如下JSON数据:

{
"price": 0.5
}

实现代码如下:

let price_str = match obj.clone() {
    JsonValue::Object(obj_data) => {
        let (_, v) = obj_data
            .into_iter()
            .find(|(k, _)| k.iter().copied().eq("price".chars()))?;
        match v {
            JsonValue::Number(val) => val,
            _ => return None,
        }
    }
    _ => return None,
};
let bits = price_str.integer as u128 * 10u128.pow(price_str.exponent as u32)
    + u128::from(price_str.fraction);
log::info!("bits: {}", bits);
// Adjust the denominator based on the desired scale
let fixed_value =
    FixedU128::saturating_from_rational(bits, 10u128.pow(price_str.fraction_length as u32));

log::info!("value of integer is {}", fixed_value);

得到日志:

2023-12-09 22:25:03.084  INFO      offchain-worker pallet_template: bits: 5    
2023-12-09 22:25:03.084  INFO      offchain-worker pallet_template: value of integer is 500000000000000000

期望fixed_value为0.5,但实际得到500000000000000000,尝试多种转换方法结果不是0就是这个大数,求正确获取价格的方式。

解决方案

核心原因说明

FixedU128默认采用18位小数精度(即基于1e18的缩放因子),所以输出的500000000000000000本质是0.5的18位精度固定点表示(0.5 × 1e18 = 5e17),这是固定点类型的正常存储逻辑,并非错误。

正确处理方式

如果需要得到可读的浮点数值或调整精度,可按以下方式处理:

  1. 转换为浮点数(适合显示/非精确计算场景)
// 将FixedU128转为f64类型
let float_price = fixed_value.to_float();
log::info!("price as float: {}", float_price); // 输出0.5
  1. 自定义固定点精度
    如果不需要18位精度,比如仅需2位小数,可重新计算缩放比例:
// 定义目标小数位数
let desired_decimals = 2;
let scaled_value = FixedU128::saturating_from_rational(bits, 10u128.pow(desired_decimals));
// 转换为带小数的字符串输出
log::info!("scaled price: {}", scaled_value.to_string()); // 输出0.50
  1. 简化lite-json解析逻辑
    原解析代码可简化,避免不必要的克隆和遍历:
// 直接通过key查找数值,无需遍历对象
let price_num = match obj {
    JsonValue::Object(obj_data) => obj_data.get("price")
        .and_then(|v| match v {
            JsonValue::Number(num) => Some(num),
            _ => None,
        })?,
    _ => return None,
};

关键注意点

  • 固定点类型(如FixedU128)的设计目的是通过整数存储实现精确计算,直接打印会输出放大后的整数,这是特性而非bug。
  • 链上/链下Worker中推荐用固定点类型做精确计算,浮点数仅适合显示场景,避免精度损失。

内容的提问来源于stack exchange,提问作者Deepak Chaudhary

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:02:32