duanbodai5166 2015-04-26 16:06
浏览 79
已采纳

迭代边界与数据类型相同

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?

  • 写回答

1条回答 默认 最新

  • douwen3500 2015-04-26 16:37
    关注

    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 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog