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

C语言实现32位16.16格式定点数库时加法运算结果错误求解

Q16.16定点数加法问题解决方案

你的定点数加法逻辑本身没有问题,完全不需要调整比特存储顺序,错误完全来自数值构造和打印环节的认知偏差。

核心问题说明

  1. 数值构造不符合预期
    你当前实现的fixed_from_parts(5,2)实际对应的十进制值是 5 + 2/65536 ≈ 5.00003,而非你以为的5.2。你把传入的小数参数直接当成了16位二进制小数的原始值,而不是十进制的小数位。
    两个数相加后得到的8.11实际含义是8 + 11/65536,和你预期的9.1完全是两套数值体系。

  2. 打印逻辑错误
    get_fixed_fractional返回的是分母为65536的分数的分子,不能直接作为十进制小数位打印。

  3. 额外优化点
    当前get_fixed_fractional的移位实现对负数不友好,建议改为直接按位取低16位:

integral_t get_fixed_fractional(const fixed_t x) {
    return (integral_t)(x & 0xFFFF);
}

修复代码

调整数值构造函数

如果你希望传入的小数参数是十进制小数点后1位的数值,需要做对应的单位转换:

fixed_t fixed_from_parts(const integral_t integral, const integral_t fractional) {
    // 先乘后除避免精度损失,将 0.1 * fractional 转换为Q16.16格式
    const fixed_t frac_part = ((fixed_t)fractional * 65536) / 10;
    return int_to_fixed(integral) + frac_part;
}

调整十进制打印函数

将二进制小数部分转换为十进制小数位后再打印:

void print_fixed_base_10(const fixed_t x) {
    // 取小数点后1位
    const int decimal_place = (get_fixed_fractional(x) * 10) / 65536;
    printf("%d.%d\n", fixed_to_int(x), decimal_place);
}

修改后运行测试代码,输出结果就是你预期的9.1。如果需要支持更多位小数,把上面代码里的10换成对应的10的N次方即可(比如打印2位小数就换成100)。

内容的提问来源于stack exchange,提问作者Caspian Ahlberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:57:04