2012-11-22 55 views
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,但没有减号。

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

回答

0

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

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

虽然这是正确的,因为位24为1,指示负1Q23分数,printf的所需的一切后位23被符号扩展。

Q1_23 FP_DataQ123 = FP_DataQ423 ; 

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

0

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