如何从64位整数中获得更高的20位?

时间:2014-01-20 17:11:01

标签: c++ objective-c c integer bits

我使用的是64位Mac OS X,我有一个NSUInteger(或uint64,它在我的系统上无关紧要)。

如何获得更高的20位NSUInteger并将其存储在另一个NSUInteger中?

您可以在C,C ++或Objective-C中回答如何做到这一点。

P.S。请不要告诉我修改所有代码并使用位字段。

P.P.S。我想我必须使用位掩码和移位?

3 个答案:

答案 0 :(得分:4)

对于uint64_t,您只需使用

即可
i >> 44

对于可能大于64位的有符号类型或类型,您还需要屏蔽较高位。

(i >> 44) & 0xFFFFF

一个较小规模的例子,

4 bits starting at pos 2 of 8.

  7   6   5   4   3   2   1   0
+---+---+---+---+---+---+---+---+
| ? | ? |       j       | ? | ? |
+---+---+---+---+---+---+---+---+

                             >> 2

+---+---+---+---+---+---+---+---+
| * | * | ? | ? |       j       |   * = 0 if unsigned or original bit7 if signed.
+---+---+---+---+---+---+---+---+ 

                   & ( 2**4 - 1 )

+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 |       j       |
+---+---+---+---+---+---+---+---+

答案 1 :(得分:0)

uint64 original = ...;
uint64 another = ((0xFFFFF00000000000 & original) >> 44);

首先使用位掩码然后向右移动44位。

答案 2 :(得分:0)

我不知道首先转换签名号码有问题。这是一个依赖于实现的功能吗?如果您在签名或未签名之前或之后为我的实现转移,那似乎并不重要:

int main()
{
  uint64_t a = std::numeric_limits<uint64_t>::max();
  int64_t  b = std::numeric_limits<int64_t>::max();
  uint64_t c = std::numeric_limits<uint64_t>::max();
  int64_t  d = std::numeric_limits<int64_t>::max();

  a = (0xFFFFF00000000000 & a) >> 44;
  b = (0xFFFFF00000000000 & b) >> 44;
  c = 0xFFFFF & (c >> 44);
  d = 0xFFFFF & (d >> 44);
  cout << "a = " << a << "; c = " << c << "; a?=c = " << (a==c) << endl;
  cout << "b = " << b << "; d = " << b << "; b?=d = " << (b==d) << endl;

  return 0;
}

这会产生:

a = 1048575; c = 1048575; a?=c = 1
b = 524287; d = 524287; b?=d = 1

$ c++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix