使用位算术从二进制 int 获取绝对值
Posted
技术标签:
【中文标题】使用位算术从二进制 int 获取绝对值【英文标题】:Getting absolute value from a binary int using bit arithmetics 【发布时间】:2016-02-05 23:40:58 【问题描述】: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 on bits 公式,但我似乎遗漏了一些东西。有任何想法吗?
【问题讨论】:
flt32
是某种非标准的浮点格式,位移是有效的吗?另见***.com/q/1723575/2564301
Jongware,偶尔,我也在下面的答案中链接到该问题。加入您的flt32
类型问题。
【参考方案1】:
flt32
是浮点类型还是 fixed point 数字类型?
我怀疑它是一种定点算术类型,而您没有正确使用它。让我解释一下。
顾名思义,定点数使用固定位置的十进制数字;这意味着它使用固定位数的小数部分。事实上,它是一个缩放的整数。
我猜您使用的flt32
类型使用整个部分的最高有效24 位和小数部分的最低有效8 位; 32 位表示的实数值是与整数相同的 32 位表示的值除以 256(即 28)。
例如,32 位数字0x00000020
被解释为整数为32
。作为小数部分使用8
位的定点数,其值为0.125
(=32/256
)。
您发布的代码是正确的,但您没有正确使用它。
使用8
十进制数字编码为定点数的数字-32
是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);
【讨论】:
【参考方案2】:int flt32_abs (int x)
^^^ ^^^
int mask=x>>31;
x=x^mask;
x=x-mask;
return x;
我已经能够通过将float
更改为int
来解决此问题并获得 32 的结果,否则代码将无法构建并出现错误:
错误:'float'和'int'类型的无效操作数到二进制'operator>>'
有关为何 C++ 中不允许对浮点数进行二进制操作的解释,请参阅
How to perform a bitwise operation on floating point numbers
我想问问更有经验的开发者,为什么代码还要为 OP 构建?我猜是宽松的编译器设置?
【讨论】:
此代码假定int
是 32 位 2 的补码。常见,但未由 C 定义。
注意:int mask=x>>31;
--> 实现定义的行为。 “实现定义行为的一个例子是当有符号整数右移时高位的传播”C11 §3.4.1
投反对票的是你吗?我要删除答案吗?在阅读上面的答案之前,我对“定点”一无所知,因为遗憾的是它没有在学校教授。
您何时收到 DV?
不确定,几个小时前我昨天第一次登录时就已经存在了。以上是关于使用位算术从二进制 int 获取绝对值的主要内容,如果未能解决你的问题,请参考以下文章