2013-04-02 19 views
1

我想寫一個定點轉換例程。我需要將兩個值加上一些標誌放入一個8字節的數據包中,所以每個值只有3個字節。爲什麼我的定點轉換爲負非整數關閉1?

我的代碼如下所示:

typedef struct 
{ 
    signed short m; 
    unsigned char f; 
} Q16_8; 

Q16_8 toQ(double d) 
{ 
    Q16_8 q; 
    q.m = (signed short)d; 
    q.f = (unsigned char)(d * 256.0); 
    return q; 
} 

double toDouble(const Q16_8 q) 
{ 
    return q.m + q.f/256.0; 
} 

我的測試結果是這樣的。其中第1列是浮點數,2是固定點,3是差值。

-2.000000 -2.000000 0.000000 
-1.750000 -0.750000 -1.000000 
-1.500000 -0.500000 -1.000000 
-1.250000 -0.250000 -1.000000 
-1.000000 -1.000000 0.000000 
-0.750000 0.250000 -1.000000 
-0.500000 0.500000 -1.000000 
-0.250000 0.750000 -1.000000 
0.000000 0.000000 0.000000 
0.250000 0.250000 0.000000 
0.500000 0.500000 0.000000 
0.750000 0.750000 0.000000 
1.000000 1.000000 0.000000 
1.250000 1.250000 0.000000 
1.500000 1.500000 0.000000 
1.750000 1.750000 0.000000 

我在做什麼錯了?

回答

2

試試這個相反:

#include <stdio.h> 

typedef struct 
{ 
    signed short m; 
    unsigned char f; 
} Q16_8; 

Q16_8 toQ(double d) 
{ 
    Q16_8 q; 
    long x = d * 256; 
    q.m = x >> 8; // this assumes >> to be an arithmetic shift 
    q.f = x & 0xFF; // this assumes signed ints to be 2's complement 
    return q; 
} 

double toDouble(Q16_8 q) 
{ 
    long x = ((long)q.m << 8) + q.f; 
    return x/256.0; 
} 

int main(void) 
{ 
    int i; 
    for (i = -2*4; i <= +2*4; i++) 
    { 
    double d = i/4.0; 
    Q16_8 q = toQ(d); 
    double d2 = toDouble(q); 
    printf("toDouble(toQ(%f)) = %f\n", d, d2); 
    } 
    return 0; 
} 

輸出(ideone):

toDouble(toQ(-2.000000)) = -2.000000 
toDouble(toQ(-1.750000)) = -1.750000 
toDouble(toQ(-1.500000)) = -1.500000 
toDouble(toQ(-1.250000)) = -1.250000 
toDouble(toQ(-1.000000)) = -1.000000 
toDouble(toQ(-0.750000)) = -0.750000 
toDouble(toQ(-0.500000)) = -0.500000 
toDouble(toQ(-0.250000)) = -0.250000 
toDouble(toQ(0.000000)) = 0.000000 
toDouble(toQ(0.250000)) = 0.250000 
toDouble(toQ(0.500000)) = 0.500000 
toDouble(toQ(0.750000)) = 0.750000 
toDouble(toQ(1.000000)) = 1.000000 
toDouble(toQ(1.250000)) = 1.250000 
toDouble(toQ(1.500000)) = 1.500000 
toDouble(toQ(1.750000)) = 1.750000 
toDouble(toQ(2.000000)) = 2.000000 
+0

是不是'X >> 8'相當於'爲x/256'?但是,這個解決方案似乎是正確 – Kupto

+0

@Kupto對[算術轉換](http://en.wikipedia.org/wiki/Arithmetic_shift)做一些研究。你可以嘗試看看[區別](http://ideone.com/ZP5oN4)。 –

+1

由於將值轉換爲負值,此代碼可能存在危險。你可以通過做掩碼等來使這個便攜式。 –

1

d = -1.75爲例,並考慮以下兩個事實的後果:

  • m-1
  • f只能是積極的......