固定点< - >双精度

时间:2012-11-22 03:52:10

标签: double fixed-point

我需要了解已签名的转化。

保证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?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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位数。