2

我需要有关签名转换的见解。

保证 C 例程的输入位于 -Pi 到 pi 的范围内。这是通过“双”数据类型传递的。

由于我的设备缺少 FPU,我必须使用 24 位寄存器上的定点对输入执行数学运算(将输入除以 Pi)。

由于范围是已知的,我能够以 Q3.10 格式存储输入数据。

所以:

 typedef int Q3_10;
 Q1_10 ReciProc_Pi = 0x145;
 Q3_10 FP_DataQ310 = (Q3_10)(Input_Data * 1024); /* Scale by 2^10 */
 Q4_20 FP_DataQ420 = FP_DataQ310 * ReciProc_Pi;  /* Input / Pi */
 Q4_23 FP_DataQ423 = FP_DataQ420 << 3; /* Change 4Q20 to 4Q23 */
 Q1_23 FP_DataQ123 = FP_DataQ423 & 0xFFFFFF; /* Retain 24 bits */

我可以使用古老的 printf 验证打印出的分数。

 double Fraction = (double)((double)FP_DataQ123 / (65536 * 128));
 printf("Fraction = %f\n", Fraction);

因此,对于诸如 2.5678 之类的输入,该分数被正确识别为 0.81483。

负数的处理方式相同吗?

当我通过 -1.757 时,上面的计算失败。printf 报告正分数 1.442410。但是 FP_DataQ123 的十六进制值似乎没问题(0xB8a0e8)。符号位正确设置为 1。

我后来这样做了:

 Q1_23 FP_DataQ123 = FP_DataQ423 & 0xFFFFFF; /* Retain 24 bits */
 if (FP_DataQ123 >> 23)
  {
    printf("Input is negative\n");
    FP_DataQ123 = (~FP_DataQ123) & 0x7FFFFF; /* Complement */ 
    double Fraction = (double)((double)FP_DataQ123 / (65536 * 128));
    printf("Fraction = %f\n", Fraction);
  }

printf 现在报告正确的分数 0.557,但没有减号。

如何在不补充 FP_DataQ123 的情况下让 printf 打印 -0.557?

4

2 回答 2

0

作为有符号整数,(65536*128)is 0x800000,它是一个负数。我认为您需要使您的文字值无符号或分两步进行除法。

于 2012-11-22T16:13:16.753 回答
0

所以事实证明,所有整数位都必须进行符号扩展。

Q1_23 FP_DataQ123 = FP_DataQ423 & 0xFFFFFF; /* Retain 24 bits */

虽然这是正确的,因为 Bit-24 是 1 表示负 1Q23 分数,但 printf 需要 Bit-23 之后的所有内容进行符号扩展。

Q1_23 FP_DataQ123 = FP_DataQ423 ; 

成功了。这种对符号扩展的需求是公平的,因为我们要求它打印一个 64 位数字而不是 24 位数字。

于 2012-11-22T18:23:15.350 回答