c - 在 C 中实现定点数的麻烦

标签 c decimal fixed-point

我正在尝试制作一个小型定点数学库。我的定点数是 32 位的,整数部分和小数部分各有 16 位。添加定点数然后查看结果值会带来麻烦。下面的函数 fixed_from_parts 接受整数部分和小数部分,并发出定点数,因此 fixed_from_parts(5, 2) 将等于 0000000000000101.0000000000000010 .

当两个数字相加时,如下面的 main 函数所示,似乎整数部分作为一个数字相加,小数部分作为另一个相加(5.2 + 3.9 错误地变成了 8.11 ,因为 5 + 3 == 8 和 2 + 9 == 11)。我认为我需要颠倒小数部分中存储的位的顺序,但我不太确定该怎么做。我是不是太复杂了?如何使加法正确工作?

#include <stdint.h>
#include <stdio.h>

typedef int16_t integral_t;
typedef int32_t fixed_t;

fixed_t int_to_fixed(const integral_t x) {
    return x << 16;
} 

integral_t fixed_to_int(const fixed_t x) {
    return x >> 16;
}

// shifts right (clears integral bits), and then shifts back
integral_t get_fixed_fractional(const fixed_t x) {
    return (integral_t) x << 16 >> 16;
}

// fixed_from_parts(5, 2) == 5.2
fixed_t fixed_from_parts(const integral_t integral, const integral_t fractional) {
    return int_to_fixed(integral) + fractional;
}

void print_fixed_base_2(const fixed_t x) {
    for (int i = (sizeof(fixed_t) << 3) - 1; i >= 0; i--) {
        putchar((x & (1 << i)) ? '1' : '0');
        if (i == sizeof(fixed_t) << 2) putchar('.');
    }
    putchar('\n');
}

void print_fixed_base_10(const fixed_t x) {
    printf("%d.%d\n", fixed_to_int(x), get_fixed_fractional(x));
}

int main(void) {
    // 5.2 + 3.9 = 9.1
    const fixed_t a = fixed_from_parts(5, 2), b = fixed_from_parts(3, 9);

    print_fixed_base_2(a);
    print_fixed_base_2(b);

    const fixed_t result = a + b;

    print_fixed_base_2(result);
    print_fixed_base_10(result); // why is the result 8.11?
}

最佳答案

你的那个不是固定点。

例子:

#define MULT    (1 << 16)

#define MAKE_FIXED(d)  ((int32_t)(d * MULT))
#define MAKE_REAL(f)   (((double)(f)) / MULT)

int32_t mulf(int32_t a, int32_t b)
{
    int64_t part = (int64_t)a * b;
    return part/MULT;
}

int32_t divf(int32_t a, int32_t b)
{
    int64_t part = ((int64_t)a * MULT) / b;
    return part;
}


int main(void)
{
    int32_t num1 = MAKE_FIXED(5.2);
    int32_t num2 = MAKE_FIXED(3.9);


    printf("%f\n", MAKE_REAL(num1 + num2));
    int32_t result = mulf(num1, num2);
    printf("%f\n", MAKE_REAL(result));
    result = divf(num1,num2);
    printf("%f\n", MAKE_REAL(result));
}

关于c - 在 C 中实现定点数的麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69383265/

相关文章:

c - 在 C 中使用 openssl RC4 header 发出编译代码

c++ - 8位十进制转二进制

MySQL查看小数位

c++ - 将十进制数转换为二进制数的意外结果

c - 我们如何为有符号浮点输入以定点表示形式进行编码?

android - 使用 RotateAnimation 在 Android 中围绕固定点旋转 ImageView

java - BigDecimal.add 奇怪的行为

c++ - cblas_dgemv 的意外结果

python - 大量小文件的 C 与 Python I/O 性能对比

c - C语言错误