首页 > 解决方案 > 如何在没有掩码的情况下检索数字(或特定位)的第一位?

问题描述

假设我们正在使用 16 位

假设我有一个算法可以从一个非常大的数字列表中检索符号。我可以做类似的事情

sign=(number>0)-(number<0)

但我想比这更有效率。

整数(或浮点数)的第一位应存储其符号值。我怎么能告诉计算机只检索我的号码的第一位?我试过这个:

sign=number>>16

这很好用,但我真的想只读取 1 位而不做任何操作。

存储这种类型的数据要容易得多。我们为每个条目执行此代码并将其存储为二进制数。

data= (data<<1) + sign

然而,检索这些数据更加复杂。假设我想读取我的号码的前 n 位或后 n 位。我们可以做类似的事情

last_10_bits= number & (0b000001111111111)
first_10_bits= (number & (0b111111111100000))>>5

这很好用,但是如果我想读取每一秒位并将其存储在 8bit 中怎么办?

bits_2nd = number % (-0b010101010101010)

这不行!我的号码中间有一堆零,如果不使用算法,我无法摆脱。这是一个很容易做的事情。

本质上,有没有办法让指针只读取我数据中的特定位?是否有任何其他语言允许这样做,或者这只能通过编写机器代码来实现?我知道我想多了,我实际上并没有为此制定算法,这只是提出难题的一种简单方法。

标签: pythonc++optimizationbit-manipulation

解决方案


正如评论中所说,你真的应该让编译器完成它的工作并使用掩码。而且,如果您想像上一个示例中那样消除间隙,则必须手动移动位。

如果您仍想访问单个位,可以使用位域结构:

struct S {
  unsigned int b : 3; // This field is 3 bits long
  unsigned int c : 1; // This one is a single bit
};

然后您可以访问单个字段:

struct S mystruct;
mystruct.b = ...;
mystruct.c = ...;

https://en.cppreference.com/w/cpp/language/bit_field


作为替代方案,您还可以使用 C++ 的std::bitset,它提供了一个很好的接口,您甚至不必手动定义结构。就像以前一样,生成的机器代码中仍然会出现班次。


这不仅仅是编程语言的问题,而是 CPU 本身的问题。一种语言或库能够提供的最大功能是在 CPU 需要用来提取各个位的移位和掩码之上的一个很好的接口


推荐阅读