Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么Q.15乘法不是';行不通_C_Printf_Signal Processing_Fixed Point - Fatal编程技术网

C 为什么Q.15乘法不是';行不通

C 为什么Q.15乘法不是';行不通,c,printf,signal-processing,fixed-point,C,Printf,Signal Processing,Fixed Point,参考我已经尝试了以下,但我完全困惑 int q = 1<<15; printf("(sys3.b0 * q) = %hx \n",((0.2929 * q))); 我希望看到257d,因为从计算器中,0.2929*32768十六进制=257d 使用这种Q.15格式有什么问题,或者只是因为打印不正确 编辑 伙计们,事实上我从没想过 我的实际代码尝试打印两个值。我认为二值打印是个问题。在@Soren的评论之后,我复制了他的代码并开始工作。然后我从printf中删除了第一个值,我的代码

参考我已经尝试了以下,但我完全困惑

int q = 1<<15;
printf("(sys3.b0 * q) = %hx \n",((0.2929 * q)));
我希望看到257d,因为从计算器中,
0.2929*32768十六进制=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)));
第二行是塞隆建议的

sys3.b0的值=0.000000000 1295

现在输出是

(sys3.b0 * q) = 4DB173CF        ((0.2929 * q)) = 3ED1CC60
(sys3.b0 * q) = 257D
您所拥有的是以下方面的结果:

0.2929 * q
是双精度的,但您正在告诉
printf
它是一个无符号的短字符。如果将结果强制转换为unsigned short,则将得到预期的结果():

打开或打开警告应该表明这是一个问题,
gcc
clang
都给出了类似的错误:

警告:格式“%hx”要求参数类型为“int”,但参数2的类型为“double”[-Wformat=]


尽管Visual Studio显然不这样做。

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

foo.c:5:33:警告:格式指定类型为“unsigned short”,但参数的类型为“double”[-Wformat]

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

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

格式字符串表示需要两个
无符号int
,即2乘以4字节*。但是你给了它一个
双精度
和一个
无符号整数
,分别是8字节和4字节*
printf
只为每个
%X
读取4个字节,因此它有效地读取了
sys3.b0*q
的8个结果,认为这8个字节是两个整数,然后进行打印

(无符号)((0.2929*q))
仍然给出相同的结果。我正在使用MS VC++将
%hx
更改为
%x
gives
3ed1cc60
。也许试着复制我上面的程序,以确保没有输入错误?你的程序可以运行!!经过测试,我发现了更奇怪的东西!让我根据我在MS VC++环境中的情况编辑这个问题,并且所有警告都已发出。类型转换的结果仍然相同output@nmxprime我添加了一个在visual studio中正确运行此代码的实例。@nmxprime仍然未定义的行为将
(sys3.b0*q)
更改为
(未签名)(sys3.b0*q)
谢谢!很好,但是anuy对这种不寻常的行为有何暗示?可能是windows的做法?现在我没有linux pc来测试它gcc@nmxprime您可以通过多种可用方法之一使用
gcc
clang
。未定义行为意味着当您指定
%X
但传入
double
时,该行为是不可预测的,因为
double
通常会大于
unsigned
,所以printf很可能从堆栈或寄存器中获取垃圾值。
printf("(sys3.b0 * q) = %hx \n",(unsigned short)(0.2929 * q));
                                ^^^^^^^^^^^^^^^^
int main() {
    int q = 1<<15;
    printf("(sys3.b0 * q) = %X \n",((unsigned)(0.2929 * q)));
}
printf("(sys3.b0 * q) = %X \t((0.2929 * q)) = %X\n",
       (sys3.b0 * q),
       (unsigned)((0.2929 * q)))