我正在尝试编写定点转换例程。我需要将两个值加上一些标志放入一个 8 字节的数据包中,因此每个值只有 3 个字节。
我的代码是这样的:
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 列是 float ,第 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
我做错了什么?
最佳答案
试试这个:
#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
关于c - 为什么我的定点转换对于负非整数会减去 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15775478/