为什么Q.15乘法不起作用

时间:2014-03-21 13:22:00

标签: c printf signal-processing fixed-point

参考Notation for fixed point representation我试过以下,但我完全糊涂了。

int q = 1<<15;
printf("(sys3.b0 * q) = %hx \n",((0.2929 * q)));

输出

((0.2929 * q)) = cc60

我希望看到257d,因为来自计算器,0.2929 * 32768 in hex = 257d

使用此Q.15格式有什么问题,或者这只是因为打印不正确


修改

伙计们,其实我从来没有想过这件事。

我的实际代码尝试打印两个值。我认为第二价值印刷是问题所在。在@Soren的评论之后我复制了他的代码并且正在工作。然后我从printf中删除了第一个值,我的代码也有效。所以我重新发布了printf语句

printf("(sys3.b0 * q) = %X \t((0.2929 * q)) = %X\n",(sys3.b0 * q),(unsigned)((0.2929 * q)));
printf("(sys3.b0 * q) = %X \n",((unsigned)(0.2929 * q)));

其中第二行是Seron建议的。

The value of sys3.b0 = 0.0000000001295

现在输出

(sys3.b0 * q) = 4DB173CF        ((0.2929 * q)) = 3ED1CC60
(sys3.b0 * q) = 257D

2 个答案:

答案 0 :(得分:1)

你拥有的是undefined behavior结果:

0.2929 * q

是一个双倍但你告诉printf这是一个未签名的短片。如果您将结果转换为 unsigned short ,您将获得预期的结果( see it live ):

printf("(sys3.b0 * q) = %hx \n",(unsigned short)(0.2929 * q));
                                ^^^^^^^^^^^^^^^^

打开或关闭警告应该表明这是一个问题,gccclang都会给出类似的错误:

  

警告:格式&#39;%hx&#39;期望类型&#39; int&#39;的参数,但参数2的类型为&#39; double&#39; [-Wformat =]

虽然显然Visual Studio没有。

答案 1 :(得分:0)

格式字符串需要的类型与您实际提供的类型不同。我的编译器说:

  

foo.c:5:33:警告:格式指定类型&#39; unsigned short&#39;但是论证的类型是&#39; double&#39; [-Wformat]

因此,您需要使用强制转换功能将0.2929 * qdouble转换为unsigned int。像这样:

int main() {
    int q = 1<<15;
    printf("(sys3.b0 * q) = %X \n",((unsigned)(0.2929 * q)));
}

编辑:当您向printf提供错误类型的参数时,它只会读取与它正在获取的思想类型相同的字节数。在你的情况下:

printf("(sys3.b0 * q) = %X \t((0.2929 * q)) = %X\n",
       (sys3.b0 * q),
       (unsigned)((0.2929 * q)))

格式字符串表示期望两个unsigned int,即两次4字节*。但是你给它一个double和一个unsigned int,它们分别是8和4个字节*。 printf只为每个%X读取4个字节,因此它有效地读取sys3.b0 * q的8结果,认为这8个字节是两个整数,然后打印出来。