迭代边界与数据类型相同
Iteration boundaries same as data type's
我的一个函数采用 min、max uint16
参数,并在某些时候迭代数值范围。但是,如果 max 恰好是 2^16-1(并且它是一个有效的用例),则溢出会中断循环逻辑。这是演示 uint8
:
问题的示例代码
package main
import "fmt"
func iter(min, max uint8) {
for i := min; i <= max; i++ {
fmt.Printf("%d, ", i)
}
}
func main() {
iter(0, 255)
}
如您所见,程序永远不会结束。在 another question 上有人提出了类似的问题,但解决方案与我遇到的问题完全相同。
我目前的想法是将循环变量转换为uint32
,类似这样:
package main
import "fmt"
func iter(min, max uint8) {
for i := uint16(min); i <= uint16(max); i++ {
fmt.Printf("%d, ", i)
}
}
func main() {
iter(0, 255)
}
然而,这似乎是一个笨拙的解决方案,不适用于 uint64
或任何最大的 uintN
类型。感觉就像我错过了一些非常基本的东西。指导?
我知道 Brad Fitz's Iter solution,但它似乎增加了不必要的开销。这也是真的吗?
例如,uint8
、
package main
import "fmt"
func iter(min, max uint8) {
{
min, max := uint(min), uint(max)
for i := min; i <= max; i++ {
fmt.Printf("%d, ", i)
}
}
}
func main() {
iter(0, 255)
}
对于uint64
,
package main
import "fmt"
func iter(min, max uint64) {
for i := min; i <= max; i++ {
fmt.Printf("%d, ", i)
if i == max {
break
}
}
}
func main() {
iter(^uint64(0)-2, ^uint64(0))
}
输出:
18446744073709551613, 18446744073709551614, 18446744073709551615
附录:
这是我的版本Dave C's suggestion。
package main
import "fmt"
func iter(min, max uint64) {
for i, next := min, min <= max; next; i, next = i+1, i < max {
fmt.Printf("%#016[1]x ", i)
}
fmt.Println()
}
func main() {
const maxUint64 = ^uint64(0)
iter(0, 3)
iter(10, 9)
iter(maxUint64-2, maxUint64)
}
输出:
0x0000000000000000 0x0000000000000001 0x0000000000000002 0x0000000000000003
0xfffffffffffffffd 0xfffffffffffffffe 0xffffffffffffffff
我的一个函数采用 min、max uint16
参数,并在某些时候迭代数值范围。但是,如果 max 恰好是 2^16-1(并且它是一个有效的用例),则溢出会中断循环逻辑。这是演示 uint8
:
package main
import "fmt"
func iter(min, max uint8) {
for i := min; i <= max; i++ {
fmt.Printf("%d, ", i)
}
}
func main() {
iter(0, 255)
}
如您所见,程序永远不会结束。在 another question 上有人提出了类似的问题,但解决方案与我遇到的问题完全相同。
我目前的想法是将循环变量转换为uint32
,类似这样:
package main
import "fmt"
func iter(min, max uint8) {
for i := uint16(min); i <= uint16(max); i++ {
fmt.Printf("%d, ", i)
}
}
func main() {
iter(0, 255)
}
然而,这似乎是一个笨拙的解决方案,不适用于 uint64
或任何最大的 uintN
类型。感觉就像我错过了一些非常基本的东西。指导?
我知道 Brad Fitz's Iter solution,但它似乎增加了不必要的开销。这也是真的吗?
例如,uint8
、
package main
import "fmt"
func iter(min, max uint8) {
{
min, max := uint(min), uint(max)
for i := min; i <= max; i++ {
fmt.Printf("%d, ", i)
}
}
}
func main() {
iter(0, 255)
}
对于uint64
,
package main
import "fmt"
func iter(min, max uint64) {
for i := min; i <= max; i++ {
fmt.Printf("%d, ", i)
if i == max {
break
}
}
}
func main() {
iter(^uint64(0)-2, ^uint64(0))
}
输出:
18446744073709551613, 18446744073709551614, 18446744073709551615
附录:
这是我的版本Dave C's suggestion。
package main
import "fmt"
func iter(min, max uint64) {
for i, next := min, min <= max; next; i, next = i+1, i < max {
fmt.Printf("%#016[1]x ", i)
}
fmt.Println()
}
func main() {
const maxUint64 = ^uint64(0)
iter(0, 3)
iter(10, 9)
iter(maxUint64-2, maxUint64)
}
输出:
0x0000000000000000 0x0000000000000001 0x0000000000000002 0x0000000000000003
0xfffffffffffffffd 0xfffffffffffffffe 0xffffffffffffffff