flt32 flt32_abs (flt32 x) {
int mask=x>>31;
printMask(mask,32);
puts("Original");
printMask(x,32);
x=x^mask;
puts("after XOR");
printMask(x,32);
x=x-mask;
puts("after x-mask");
printMask(x,32);
return x;
}
这是我的代码,在值-32上调用函数返回.125。我感到很困惑,因为它是一个相当直接的abs的公式,但我似乎错过了一些东西。有任何想法吗?
答案 0 :(得分:2)
flt32
是浮点数还是fixed point数字?
我怀疑它是固定点算术的一种类型,你没有正确使用它。让我解释一下。
如名称所示,定点数用于十进制数字的固定位置;这意味着它对小数部分使用固定的位数。事实上,它是一个缩放的整数。
我猜你正在使用的flt32
类型使用整个部分的最高有效24位,小数部分使用最低有效8位;作为32位表示的实数的值是与整数相同的32位表示的值,除以256(即2 8 )。
例如,32位数0x00000020
被解释为整数32
。作为小数部分使用8
位的定点数,其值为0.125
(=32/256
)。
您发布的代码是正确的,但您没有正确使用它。
使用-32
十进制数字编码为定点数的8
为0xFFFFE000
,它是-8192
(=-32*256
)的整数表示。该算法正确生成8192
0x00002000
(=32*256
);当它被解释为定点时,这也是32
。
如果将-32
传递给函数而不注意将其编码为定点,则会正确地将其转换为32
并返回此值。但32
(0x00000020
)是0.125
(=1/8=32/256
),当它被解释为定点时(我假设函数printMask()
会这样做)。
如何正确测试代码?
你可能有一个从整数创建定点数的函数。使用它来获取-32
的正确表示,并将该值传递给flt32_abs()
函数。
如果您没有这样的功能,很容易编写它。只需将整数与256
相乘(或者甚至更好,将其左移8位),这就是全部:
function int_to_fx32(int x)
{
return x << 8;
}
定点库通常使用宏进行此类转换,因为它们可以生成更快的代码。表示为宏,它看起来像这样:
#define int_to_fx32(x) ((x) << 8)
现在你进行测试:
fx32 negative = int_to_fx32(-32);
fx32 positive = fx32_abs(negative);
// This should print 32
printMask(positive, 32);
// This should print 8192
printf("%d", positive);
// This should print -8192
printf("%d", negative);
// This should print 0.125
printMask(32, 32);
答案 1 :(得分:0)
int flt32_abs (int x) {
^^^ ^^^
int mask=x>>31;
x=x^mask;
x=x-mask;
return x;
}
我已经能够通过将float
更改为int
来解决此问题并获得32的结果,否则代码将无法构建并显示错误:
错误:类型'float'和'int'到二进制'运算符&gt;&gt;'的无效操作数'
有关为什么C ++中不允许对浮点数进行二进制运算的解释,请参阅
How to perform a bitwise operation on floating point numbers
我想问更有经验的开发人员,为什么代码甚至为OP构建?我觉得放松的编译器设置?