迭代边界与数据类型相同 [英] Iteration boundaries same as data type's

查看:232
本文介绍了迭代边界与数据类型相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数需要 min max uint16 参数,并且在某个点迭代数值范围。但是,如果 max 碰巧是 2 ^ 16-1 (并且它是一个有效的用例),那么溢出会中断循环逻辑。以下是一个演示 uint8 问题的示例代码:

  package main 

importfmt

func iter(min,max uint8){
for i:= min; i <= max; i ++ {
fmt.Printf(%d,,i)
}
}

func main(){
iter(0,255 )
}

正如您所看到的,程序永远不会结束。在另一个问题上也提到了类似的问题,但解决方案恰好显示了我遇到的同样问题。



我现在的想法是将循环变量转换为 uint32 ,与此类似:

 









$ (分钟);我< = uint16(最大); i ++ {
fmt.Printf(%d,,i)
}
}

func main(){
iter(0,255 )
}

然而,这似乎是一个笨拙的解决方案,这不会为 uint64 或最大的 uintN 类型工作。感觉就像我缺少一些非常基本的东西。指导?



我知道 Brad Fitz的Iter解决方案,但似乎增加了不必要的开销。这是真的吗?

解决方案

例如,对于 uint8

 包主

导入fmt

函数(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 < code $,b
$ b $ pre $



$ b $ $ b 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 
$ p


$ p $

附录

我的 Dave C 建议

 包主

导入fmt

func iter(min,max uint64){
for i,next:= min,min <= max;下一个; 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


A function I have takes min, max uint16 parameters and at some point iterates over the numeric range. However, if max happens to be 2^16-1 (and it is a valid use case), then overflow breaks the loop logic. Here is an example code demonstrating the problem with 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)
}

As you can see, the program never ends. A similar question was asked at another question but the solution exactly exhibits the same problem I have.

My thinking for now is to convert the loop variable to uint32, similar to this:

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)
}

However, this seems to be a clumsy solution, which is not going to work for uint64 or whatever biggest uintN type. Feels like I am missing something very basic. Guidance?

I am aware of Brad Fitz's Iter solution, but it seems to add unneeded overhead. Is that true as well?

解决方案

For example, for 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)
}

For 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))
}

Output:

18446744073709551613, 18446744073709551614, 18446744073709551615

Addendum:

Here's my version of 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)
}

Output:

0x0000000000000000 0x0000000000000001 0x0000000000000002 0x0000000000000003 
0xfffffffffffffffd 0xfffffffffffffffe 0xffffffffffffffff 

这篇关于迭代边界与数据类型相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆