简体   繁体   English

将负号添加到未签名的更快方法

[英]Faster way of adding negative signed to unsigned

Assuming I have a: usize and a negative b:isize how do I achieve the following semantics - reduce a by absolute value of b in fastest manner possible? 假设我有a: usize和一个否定的b:isize我如何实现以下语义-以最快的方式将a的绝对值减少b

I already thought of a - (b.abs() as usize) , but I'm wondering if there is a faster way. 我已经想到a - (b.abs() as usize) ,但是我想知道是否有更快的方法。 Something with bit manipulation, perhaps? 有点操纵的东西吧?

Why do you assume this is slow? 您为什么认为这很慢? If that code is put in a function and compiled, on x86-64 linux, it generates the following: 如果将该代码放入函数中并在x86-64 linux上编译,它将生成以下内容:

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

That's assuming it doesn't get inlined... which I had to work at for a few minutes to prevent the optimiser from doing in order to get the above. 那是假设它没有被内联。。。我不得不工作几分钟,以防止优化器为了得到上面的结果而工作。

That's not to say it definitely couldn't be done faster, but I'm unconvinced it could be done faster by much . 这并不是说一定不能做得更快,但我不相信这是可以做到的快得多。

If b is guaranteed to be negative, then you can just do a + b . 如果保证b为负,那么您可以做a + b

In Rust, we must first cast one of the operands to the same type as the other one, then we must use wrapping_add instead of simply using operator + as debug builds panic on overflow (an overflow occurs when using + on usize because negative numbers become very large positive numbers after the cast). 在Rust中,我们必须首先将一个操作数转换为与另一操作数相同的类型,然后必须使用wrapping_add而不是简单地使用operator +因为debug在溢出时会产生恐慌(在usize上使用+时会发生溢出,因为负数变为转换后的非常大的正数)。

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

With optimizations, wrapping_add compiles to a single add instruction. 通过优化, wrapping_add编译为一条add指令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM