打印
[牛人杂谈]

固定点数运算你会吗?

[复制链接]
455|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wahahaheihei|  楼主 | 2024-2-27 16:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在计算机科学中,固定点数表示一种用于表示实数的方法,它将小数点固定在某个位置上,而不像浮点数那样可以在数值中移动。在 C 语言中,固定点数通常用于实现对小数进行精确计算的需求,特别是在没有浮点处理器的嵌入式系统中。

固定点数的表示方式类似于整数,但需要额外的规则来确定小数点的位置。通常,我们将一个整数视为包含小数点右侧一定位数的小数。例如,如果我们有一个16位的整数,我们可以将其解释为包含小数点右侧4位的小数。这意味着我们可以使用该整数表示范围内的值来表示从0到最大值之间的所有小数。通过这种方式,我们可以进行固定点数的计算,而不会丢失精度。

以下是一个简单的示例,展示如何在 C 语言中进行固定点数的加法运算:
#include <stdio.h>

#define FIXED_POINT_SHIFT 16 // 假设小数点右移16位

// 固定点数加法
int fixed_point_add(int a, int b) {
    return a + b;
}

int main() {
    int fixed_a = 100 << FIXED_POINT_SHIFT; // 将整数100左移16位,表示固定点数
    int fixed_b = 200 << FIXED_POINT_SHIFT; // 将整数200左移16位,表示固定点数

    int result = fixed_point_add(fixed_a, fixed_b);

    printf("Fixed Point Result: %d\n", result);
    printf("Float Point Result: %f\n", (float)result / (1 << FIXED_POINT_SHIFT)); // 将结果转换为浮点数输出

    return 0;
}
在这个示例中,我们假设小数点右移16位,然后将整数100和200分别转换为固定点数。然后,我们调用 fixed_point_add() 函数对这两个固定点数进行加法运算。最后,我们将结果打印出来,同时通过除以 2 的 16 次方将其转换回浮点数进行打印。

需要注意的是,在固定点数运算中,需要小心处理溢出和精度问题。由于固定点数的表示范围有限,可能会导致结果溢出或者失去精度。因此,在进行固定点数运算时,需要确保适当地选择表示位数,并且小心处理可能出现的溢出情况。

使用特权

评论回复
沙发
wahahaheihei|  楼主 | 2024-2-27 16:03 | 只看该作者
typedef int16_t fixed_t;

#define FIXED_SHIFT 8
#define FLOAT_TO_FIXED(f) ((fixed_t)((f) * (1 << FIXED_SHIFT)))
#define FIXED_TO_FLOAT(f) ((float)(f) / (1 << FIXED_SHIFT))

fixed_t fixed_multiply(fixed_t a, fixed_t b) {
    return (fixed_t)(((int32_t)a * (int32_t)b) >> FIXED_SHIFT);
}

使用特权

评论回复
板凳
wahahaheihei|  楼主 | 2024-2-27 16:03 | 只看该作者
在某些嵌入式系统中,浮点运算会较慢或不被支持。因此,使用固定点数运算可以提供一种有效的浮点数近似解决方案。

使用特权

评论回复
地板
heisexingqisi| | 2024-2-27 17:02 | 只看该作者
降低浮点开销的方法。

使用特权

评论回复
5
幸福小强| | 2024-2-28 17:05 | 只看该作者
如果知道要保留多少其实可以先放大,再运算,舍弃掉余数。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

217

主题

3063

帖子

12

粉丝