Bithack技巧整理合集

一些实用的Bithack技巧,n皇后问题,以及Rust中std提供的函数

引言

为什么要学bithack?这个视频或许能给出答案

而上周末跟数学系同学讲解数据类型的时候让我意识到,能够理解不同数据类型在内存中的表达方式,是"会用python"和”懂编程“之间一层重要的台阶。 当然,最后还是会发现,写代码的本质终究是数学 - 微积分,线代,离散,和Boolean Algebra

那么先简单总结一下这个视频中的技巧

代码尚未测试

const NEWTON_ITER: usize = 1;
fn inverse_sqrt(mut num: f64) -> f64{
    //edge cases
    if !num.is_sign_positive() || num.is_nan(){ return f64::NAN; }
    if num.is_subnormal(){ return f64::INFINITY; }
    if num.is_infinity(){ return 0.0 }
    
    let tmp: f64 = num * 0.5;
    //cast binary representation of f64
    let mut x = num.to_bits();
    //the magic happens
    x = 0x5f3759df - (x >> 1);
    //cast back
    num = f64::from_bits(x);
    //Newton's approximation
    for _ in 0..NEWTON_ITER{ num = num * ( 1.5 - (tmp * num * num) ); }
    num
}

笔记

基础 - 改变指定位置的值

x = (1<<k) |  x; //将kth bit设定为1
x = ~(1<<k) & x; //将kth bit设定为0
x = (1<<k) ^ x; //将kth bit翻转

Trailing Zeros -> Ones

x = x | (x-1); //将trailing zero全变成1 x = x & (x-1); //将最后一个1改成0 x = x & -x; //只保留最后一个1

2s compliment

//下面式子中x始终为正 -x = (~x) + 1; //正->负 x = ~((-x)-1); //负->正

Masks

x = a & mask; //只拷贝mask下的内容 y = a & ~mask; //只拷贝不在mask下的内容 z = x | y; //两个在一起可以完美组合成新的值

Swapping bits

p = (x >> a) ^ (x >> b) & 1; //判断a bit与b bit是否相同,若不同,则p = 0
x ^= (p << a);
x ^= (p << b);

Kernighan’s Population Count

每次都使用 x = x & (x-1), 直到x = 0 这种方法速度很慢,如果需要population count, rust中有u32::count_ones() 使用的是CPU指令集内置的功能 Leetcode-191 我此题的题解

Counting bit islands

(x&1) + ( x.count_ones(x ^ (x >> 1)) /2 ) x & 1可以理解为将x右移的最后一位转回到最高位,然后进行异或计算

Bit Scan Forwards(BSF)

fn bsf(mut x: u32) -> usize{
    if x == 0 {return 0;}
    x = x & -x; //只保留最后一个1
    ((x & 0xffff0000) != 0) as usize * 16
      + ((x & 0xff00ff00) != 0) as usize * 8
      + ((x & 0xf0f0f0f0) != 0) as usize * 4
      + ((x & 0xcccccccc) != 0) as usize * 2
      + ((x & 0xaaaaaaaa) != 0) as usize
}

这个可能跟Population count 一样不是最优解法,rust中有u32::trailing_zeros()u32::trailing_ones()

Next Lexicographic Permutation

Given a bit string, generate the next permutation above with the same number of 1s

Licensed under CC BY-NC-SA 4.0
Sep 17, 2022 17:06 -0400