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

4

2 回答 2

2

flt32浮点数还是定点数的类型?

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

顾名思义,定点数使用十进制数字的固定位置。这意味着它使用固定位数的小数部分。事实上,它是一个缩放的整数。

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

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

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

使用十进制数字编码为定点数的数字是( -32)的整数表示。该算法正确地产生了( ); 这也是它被解释为定点的时候。80xFFFFE000-8192=-32*25681920x00002000=32*25632

如果您传递-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);
于 2016-02-06T01:07:58.053 回答
0
int flt32_abs (int x) {
^^^            ^^^
    int mask=x>>31;
    x=x^mask;
    x=x-mask;
    return x;
}

我已经能够通过更改float为来解决此问题并获得 32 的结果int,否则代码将不会生成错误:

错误:“float”和“int”类型的无效操作数到二进制“operator>>”

有关为什么 C++ 中不允许对浮点数进行二进制操作的解释,请参见

如何对浮点数执行按位运算

我想问问更有经验的开发者,为什么代码还要为 OP 构建?我猜是宽松的编译器设置?

于 2016-02-06T00:00:04.967 回答