2

符号付き変換についての洞察が必要です。

C ルーチンへの入力は、-Pi から pi の範囲にあることが保証されています。これは「double」データ型で渡されます。

私のデバイスには 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 の 16 進数値は問題ないようです (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)は です0x800000。これは負の数です。リテラル値を符号なしにするか、除算を2段階で行う必要があると思います。

于 2012-11-22T16:13:16.753 に答える
0

したがって、すべての整数ビットを符号拡張する必要があることがわかりました。

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

ビット 24 は負の 1Q23 分数を示す 1 であるため、これは正しいのですが、printf ではビット 23 以降のすべてを符号拡張する必要がありました。

Q1_23 FP_DataQ123 = FP_DataQ423 ; 

トリックを行います。24 ビットの数値ではなく 64 ビットの数値を出力するように求めているため、この符号拡張の必要性は十分に公平です。

于 2012-11-22T18:23:15.350 に答える