c - 尝试解决 C 语言中的位级操作难题时遇到困难

标签 c bit-manipulation

所以我必须使用按位操作来解决这个问题。

Should duplicate effect of C expression (x*63),
including overflow behavior.
Examples: multi63(1) = 63
   multi63(-1) = -63
Available ops: ! ~ & ^ | + << >>

也许我不明白正在寻找什么,但我尝试不同的变化,每次我的结果要么非常接近需要返回的结果,要么不正确。

这就是我现在正在玩的。我想如果我可以掩盖 x,即周长 1,那么我就会知道我是乘以负数还是正数。

int y = x>>31;

return ~(y^x) 

这将返回:

 Test times63(2147483647[0x7fffffff]) failed...
...Gives -2147483648[0x80000000]. Should be 2147483585[0x7fffffc1]

如果我尝试返回 2147483585[0x7fffffc1] 它告诉我我需要返回 -2147483648[0x80000000] 所以我对需要返回什么感到困惑。

最佳答案

作为一般(!)规则,您可以考虑表达式 x*N 的这些公式,仅使用移位和加法/减法:

A: (x << n) + (x << n-1) << + ... + << (x << m)

B:(x << n+1) - (x << m)

N 可以被视为 0 和 1 的序列 [(0...0)(1...1)(0...0)(1...1)]。您必须考虑从位位置 n 到位位置 m 连续运行 1,其中 n == m 是可能的。

在您的情况下,N = 63,即二进制的 011_1111。所以我们有 n = 5 和 m = 0。 作为一个简单的例子,假设 x = 2:

使用B: (2 << 6) - (2 << 0) == (2*64) - (2*1) == 128 - 2 == 126 (你可以自己尝试一下A,它工作得很好。)

为了演示另一个数字的过程,假设 N = 55 且 x = 2. 55(二进制:011_0111)。这次我们有两个 1 序列。 n1 = 5、m1 = 4、n2 = 2、m2 = 0。

使用 B 表示 n1/m1:(2 << 6) - (2 << 4) == (2*64) - (2*16) == 128 - 32 == 96

使用 B 表示 n2/m2:(2 << 3) - (2 << 0) == (2*8) - (2*1) == 16 - 2 == 14

将两个结果相加得到 110,即所需的值。

关于c - 尝试解决 C 语言中的位级操作难题时遇到困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29870349/

相关文章:

java - 将byte []数组的元素组合成16位数字

c - 执行按位 & 时导致编译器错误的原因是什么?

c - 在C中输出两个二进制字符串及其十进制值相加的结果

c - 确定 32 位 int 的符号

c - 我怎么知道 exit() 函数是如何工作的?

c - 如何在二进制文件中写入指针? (C)

c - memchr 返回意外字符

c - 在 C 中翻转 double /浮点符号的最快方法

c - 如何从结构中读取数据指针?

c - 指针算术的差异 (&x[5]-x)