使用位算术从二进制int获取绝对值

时间:2016-02-05 23:40:58

标签: c bit-manipulation mask absolute-value

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的公式,但我似乎错过了一些东西。有任何想法吗?

2 个答案:

答案 0 :(得分:2)

flt32是浮点数还是fixed point数字?

我怀疑它是固定点算术的一种类型,你没有正确使用它。让我解释一下。

如名称所示,定点数用于十进制数字的固定位置;这意味着它对小数部分使用固定的位数。事实上,它是一个缩放的整数。

我猜你正在使用的flt32类型使用整个部分的最高有效24位,小数部分使用最低有效8位;作为32位表示的实数的值是与整数相同的32位表示的值,除以256(即2 8 )。

例如,32位数0x00000020被解释为整数32。作为小数部分使用8位的定点数,其值为0.125=32/256)。

您发布的代码是正确的,但您没有正确使用它。

使用-32十进制数字编码为定点数的80xFFFFE000,它是-8192=-32*256)的整数表示。该算法正确生成8192 0x00002000=32*256);当它被解释为定点时,这也是32

如果将-32传递给函数而不注意将其编码为定点,则会正确地将其转换为32并返回此值。但320x00000020)是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构建?我觉得放松的编译器设置?