如何使用按位运算符将任何负值转换为零?
How to convert any negative value to zero with bitwise operators?
我正在为 Go 中的 LinkedList 编写 PopBack()
操作,代码如下所示:
// PopBack will remove an item from the end of the linked list
func (ll *LinkedList) PopBack() {
lastNode := &ll.node
for *lastNode != nil && (*lastNode).next != nil {
lastNode = &(*lastNode).next
}
*lastNode = nil
if ll.Size() != 0 {
ll.size -= 1
}
}
我不喜欢最后一个 if
条款;如果大小为零,我们不想减少到负值。我想知道是否有一个按位运算,其中无论递减后的值是什么,如果它 只是负数 它应该转换为零?
负值设置了符号位,所以你可以这样做
ll.size += (-ll.size >> 31)
假设ll.size
是int32
和ll.Size()
returnsll.size
。当然这也意味着 size 永远不会是负数。当大小为正时,右移将符号扩展 -ll.size
使其为 -1,否则将为 0
如果 ll.size
是 int64
然后将轮班计数更改为 63。如果 ll.size
是 uint64
你可以简单地 cast to int64
if the size is never larger than 263. But if the size can be that large (although almost impossible to occur in the far future) then things are much more trickier:
mask := uint64(-int64(ll.size >> 63)) // all ones if ll.size >= (1 << 63)
ll.size = ((ll.size - 1) & mask) | ((ll.size + uint64(-int64(ll.size) >> 63)) & ^mask)
它基本上是一个 bitwise mux that's usually used in bithacks 因为如果没有 if
在 golang
中你不能将 bool 转换为 int
乍一看,这些都不太可读,所以 if
块通常更好
将循环的每次迭代中的 nil 检查换成循环之前的单个 nil 检查。通过此更改,循环运行得更快,更新大小的运算符是减法。
func (ll *LinkedList) PopBack() {
if ll.node == nil {
return
}
lastNode := &ll.node
for (*lastNode).next != nil {
lastNode = &(*lastNode).next
}
*lastNode = nil
ll.size -= 1
}
我正在为 Go 中的 LinkedList 编写 PopBack()
操作,代码如下所示:
// PopBack will remove an item from the end of the linked list
func (ll *LinkedList) PopBack() {
lastNode := &ll.node
for *lastNode != nil && (*lastNode).next != nil {
lastNode = &(*lastNode).next
}
*lastNode = nil
if ll.Size() != 0 {
ll.size -= 1
}
}
我不喜欢最后一个 if
条款;如果大小为零,我们不想减少到负值。我想知道是否有一个按位运算,其中无论递减后的值是什么,如果它 只是负数 它应该转换为零?
负值设置了符号位,所以你可以这样做
ll.size += (-ll.size >> 31)
假设ll.size
是int32
和ll.Size()
returnsll.size
。当然这也意味着 size 永远不会是负数。当大小为正时,右移将符号扩展 -ll.size
使其为 -1,否则将为 0
如果 ll.size
是 int64
然后将轮班计数更改为 63。如果 ll.size
是 uint64
你可以简单地 cast to int64
if the size is never larger than 263. But if the size can be that large (although almost impossible to occur in the far future) then things are much more trickier:
mask := uint64(-int64(ll.size >> 63)) // all ones if ll.size >= (1 << 63)
ll.size = ((ll.size - 1) & mask) | ((ll.size + uint64(-int64(ll.size) >> 63)) & ^mask)
它基本上是一个 bitwise mux that's usually used in bithacks 因为如果没有 if
在 golang
乍一看,这些都不太可读,所以 if
块通常更好
将循环的每次迭代中的 nil 检查换成循环之前的单个 nil 检查。通过此更改,循环运行得更快,更新大小的运算符是减法。
func (ll *LinkedList) PopBack() {
if ll.node == nil {
return
}
lastNode := &ll.node
for (*lastNode).next != nil {
lastNode = &(*lastNode).next
}
*lastNode = nil
ll.size -= 1
}