2012-11-22 58 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,它是一個負數。我認爲你需要使你的字面值無符號或分兩步進行。