假设我们有一个mask变量,它可以是0(全部zoom )或-1(全部为1).

我有另一个变量x,比方说42.

导致以下结果的按位表达式是什么(可能):

  • 1mask == 0
  • xmask == -1

我试图做的是探索消除以下if条语句的方法

unsigned x = 3;
unsigned some_number = 42;

// ~~~

if (some_number % x == 0)
{
    some_number /= x;
}

关于我正在处理的特定问题中的type个变量(见下文),所有的数字都是无符号整数,例如unsigned.


EDIT 2 (MISTAKE):我做了一个mistake,忘记了掩码是0(all zeros)或-1(all ones),这是我之前说的1(只是其最低有效位是1).Please accept my apologies as I wasted your precious time.


EDIT 1:

总体而言,重点是使用if-else个构造(包括条件运算符(?:)).相反,我正在寻找与branchless个实践中使用的位操作类似的位操作.这个问题不是它在这种情况下是否会表现得更好,也不是答案是否可以被认为是一种好的做法.这只是为了探索比特操纵的世界.


这是我的try

// Check whether some_number is divisible by x
unsigned mask = ((some_number % x) - 1) >> 31;
unsigned deonm = // ??
some_number =/ denom

我用它来回答欧拉项目的third个问题,代码如下

size_t largest_prime_factor(size_t number)
{
    if (number < 2) return 0;
    if (number == 2) return 2;
    while ((number & 1) == 0)
    {
        number >>= 1;
    }
    size_t lpf = 2;
    size_t i = 3;
    size_t max_iter = sqrt(number);
    while (i < max_iter)
    {
        size_t mask = ((number % i) - 1) >> 31;
        lpf = (i & mask) | (lpf & ~mask);
        number /= X; // mask = 0 => X=1; mask = 1 => X=i
        i += 2;
    }
    return lpf;
}

注:如果可能,请建议一个更好的标题.

推荐答案

我将假设掩码(我将称为m)为x,结果(我将称为r)是相同大小的无符号整数类型.我称它为TYPE式.


对于大多数比特来说,这很容易:ri=xi&;mi

但最低有效位(r0)是不同的.下面显示了基于m0和x0的值的r0的期望值:

r0 m0 = 0 m0 = 1
x0 = 0 1 0
x0 = 1 1 1

因此我们得到r0=~m0|x0

现在,我们只需要将它们结合起来.

我们希望将第一条规则应用于除最后一位之外的所有位.这可以通过使用允许通过除最后一位(... & ( ~(TYPE)1 ))之外的所有位的掩码来实现.

我们只想对最后一点应用第二条规则.这可以通过使用仅允许通过最后一位(... & 1)的掩码来实现.

总而言之:

r = ( x & m & ( ~(TYPE)1 ) ) | ( ( ~m | x ) & 1 );

现在,我们有了一个仅具有位操作的解决方案(以及可以通过使用正确的数字文字后缀来避免的强制转换).

C++相关问答推荐

为指针 struct 创建宏

有效地计算由一组点构成的等边三角形和等腰三角形的数量

需要大整数和浮点数.使用long long int和long double

两个连续的语句是否按顺序排列?

在C++中头文件中声明外部 struct

字符是否必须转换为无符号字符,然后才能与getc家族的返回值进行比较?

错误Cygwin_Except::Open_stackdupfile:正在转储堆栈跟踪是什么?

用C++从外部ELF符号读取值

在另一个函数中使用realloc和指针指向指针

致命错误:ASM/rwan ce.h:没有这样的文件或目录.符号链接还不够

C语言中神秘的(我认为)缓冲区溢出

如何在双向表中实现线程安全,每个条目仅使用4位,同时避免任何全局锁?

无法识别C编程语言的语法,如书中所示

当读取可能会阻塞管道中的父进程时,为什么要等待子进程?

指向返回 struct 成员的指针,安全吗?

C 错误:对 int 数组使用 typedef 时出现不兼容的指针类型问题

如何使用 VLA 语法使用 const 指针声明函数

是否可以在多字 C 类型中的任何位置混合存储和类型限定符?

malloc:损坏的顶部大小无法找出问题

Clang 是否为内联汇编生成了错误的代码?