我拥有的函数采用 min , max uint16参数,并在某些时候迭代数字范围。但是,如果 max 恰好是 2 ^ 16-1 (这是一个有效的用例),则溢出会破坏循环逻辑。这是示例代码,演示了以下问题uint8:
uint16
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) }
如您所见,该程序永远不会结束。在另一个问题上也提出了类似的问题,但是解决方案恰好显示出我遇到的相同问题。
我现在的想法是将循环变量转换为uint32,类似于:
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类型的解决方案。感觉像我缺少一些非常基本的东西。指导?
uint64
uintN
我知道Brad Fitz的Iter解决方案,但这似乎增加了不必要的开销。那是真的吗?
例如,对于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
附录 :
这是我对DaveC的建议。
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