参考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
答案 0 :(得分:1)
你拥有的是undefined behavior结果:
0.2929 * q
是一个双倍但你告诉printf
这是一个未签名的短片。如果您将结果转换为 unsigned short ,您将获得预期的结果( see it live ):
printf("(sys3.b0 * q) = %hx \n",(unsigned short)(0.2929 * q));
^^^^^^^^^^^^^^^^
打开或关闭警告应该表明这是一个问题,gcc
和clang
都会给出类似的错误:
警告:格式&#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 * q
从double
转换为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个字节是两个整数,然后打印出来。