我需要了解已签名的转化。
保证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?
答案 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位数。