所以我试图绕过定点数字。到现在为止还挺好。让我困惑的唯一一件事是数字的“分数”部分。
我对定点数的理解是它根据比例(在这种情况下等于8位)分割二进制数。左侧是整数部分,分数是右侧。
XXX.Y
其中XXX
是整数/整数部分的三个字节,而Y
是小数部分的一个字节(如果我错了,请纠正我)。
我们采用以下宏:
#define FIX_SCALE 8
#define FIX_FRACTION_MASK ((1 << FIX_SCALE) - 1)
#define FIX_WHOLE_MASK ~FIX_FRACTION_MASK
#define FIX_FROM_FLOAT(X) ((X) * (1 << FIX_SCALE))
#define FIX_TO_FLOAT(X) ((float)(X) / (1 << FIX_SCALE))
#define FIX_TO_INT(X) ((X) >> FIX_SCALE)
#define FIX_FROM_INT(X) ((X) << FIX_SCALE)
#define FIX_FRACTION(X) ((X) & FIX_FRACTION_MASK)
#define FIX_WHOLE(X) ((X) & FIX_WHOLE_MASK)
考虑以下示例:
int Fixed = FIX_FROM_FLOAT(2.5f);
结果整数值为640
,0x280
为十六进制,0000 0000 0000 0000 0000 0010 1000 0000
为二进制。
我们先取两个字节:0000 0010 1000 0000
我理解0000 0010
的来源,它是整数部分(2
)。但我得不到的是1000 0000
这是小数部分。我只是看不出它与数字5的关系(二进制为0101)。我本来期望像0101 0000
或0000 0101
这样的东西 - 显然我在这里误解了一个基本概念。
如果我写:
int Fraction = FIX_FRACTION(Fixed);
我会得到128
(0x80
十六进制。这是有道理的,因为它掩盖了整数部分2
)。我第一次写这篇文章的时候,我希望得到一个5
。
如果我写的话,我会得到0.5
:
float Fraction = FIX_TO_FLOAT(FIX_FRACTION(Fixed));
有人可以为我清除这种困惑吗?为什么分数0000 1000
中没有101
?为什么我们必须FIX_TO_FLOAT
FIX_FRACTION
来获得正确的分数?
感谢。
答案 0 :(得分:1)
整数代表10的不同幂:
(source)
所以10203 = 1×10000 + 0×1000 + 2×100 + 0×10 + 3×1
小数点继续这种模式,代表10的负幂:
所以0.10203 = 1/10 + 0/100 + 2/1000 + 0/10000 + 3/100000
十进制数2.5在2s列中有一个“ 2”,在1 / 10ths列中有一个“ 5”,因此总数为2×1 + 5/10。
二进制不动点的工作原理完全相同,不同之处在于2的幂而不是10。整数部分是1s列,2s列,4s列,8s列等,小数部分是1 / 2s列,1 / 4th列,1 / 8th列等。
例如,如果数字为4.4格式,其中第一个半字节是无符号整数部分,第二个半字节是小数部分,那么对于二进制数1010 1001,整数部分表示
1×8 + 0×4 + 1×2 + 0×1
小数部分代表
1/2 + 0/4 + 0/8 + 1/16
因此,十进制等效值为
1×8 + 0×4 + 1×2 + 0×1 + 1/2 + 0/4 + 0/8 + 1/16
= 10.5625
签名版本相似:
(source)
因此,在您的二进制格式中,其中2.5是0b0000 0010 1000 0000
,第一个字节在2s列中为1,在1s列中为0,所以它是
... + 0×4 + 1×2 + 0×1 + 1/2 + 0/4 + 0/8 + ...
答案 1 :(得分:0)
比较十进制和二进制表示中的数字模式不起作用。 让我们暂时忘记定点数,看看5和50的二进制表示:
5: 0000'0101
50: 0011'0010
如您所见,小数5的二进制模式也无法在十进制50的二进制表示中找到。
现在要理解为什么十进制0.5在Q23.8二进制中是..00&#39; 1000&00; 0000,你需要遵循二进制到十进制转换规则:
将每1替换为2 ^位置并加上数字
position: 7 6 5 4 3 2 1 0 -1-2-3-4 -5-6-7-8
binary number: 0 0 0 0 0 0 1 0 . 1 0 0 0 0 0 0 0
2 ^ 1 + 2 ^ -1 = 2 + 0.5 = 2.5
答案 2 :(得分:-1)
右边的二进制值。是1/2 1/4 1/8等 因此10.1二进制是2.5