更快的方式添加负签名到无符号

时间:2015-06-12 09:37:04

标签: bit-manipulation rust

假设我有a: usize和否定b:isize,我如何实现以下语义 - 以最快的方式减少b 的绝对值?

我已经想过a - (b.abs() as usize),但我想知道是否有更快的方法。也许有点操纵的东西?

2 个答案:

答案 0 :(得分:4)

为什么你认为这很慢?如果将该代码放在函数中并进行编译,则在x86-64 linux上生成以下代码:

_ZN6simple20h0f921f89f1d823aeeaaE:
    mov rax, rsi
    neg rax
    cmovl rax, rsi
    sub rdi, rax
    mov rax, rdi
    ret

假设它没有内联...我必须工作几分钟才能阻止优化器进行以上操作。

这并不是说它绝对不能更快地完成,但我不相信它可以通过很多更快地完成。

答案 1 :(得分:2)

如果保证b为否定,那么您可以a + b

在Rust中,我们必须首先将一个操作数转换为与另一个操作数相同的类型,然后我们必须使用wrapping_add而不是简单地使用运算符+,因为调试会在溢出时建立恐慌(在+上使用usize时会发生溢出,因为在投射后,负数会变为非常大的正数。

fn main() {
    let a: usize = 5;
    let b: isize = -2;
    let c: usize = a.wrapping_add(b as usize);
    println!("{}", c); // prints 3
}

通过优化,wrapping_add可以编译为单个add指令。