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

报告相同问题?

悬赏问题

  • ¥50 MATLAB APP 制作出现问题
  • ¥15 wannier复现图像时berry曲率极值点与高对称点严重偏移
  • ¥15 利用决策森林为什么会出现这样·的问题(关键词-情感分析)
  • ¥15 DispatcherServlet.noHandlerFound No mapping found for HTTP request with URI[/untitled30_war_e
  • ¥15 使用deepspeed训练,发现想要训练的参数没有梯度
  • ¥15 寻找一块做为智能割草机的驱动板(标签-stm32|关键词-m3)
  • ¥15 信息管理系统的查找和排序
  • ¥15 基于STM32,电机驱动模块为L298N,四路运放电磁传感器,三轮智能小车电磁组电磁循迹(两个电机,一个万向轮),怎么用读取的电磁传感器信号表示小车所在的位置
  • ¥15 如何解决y_true和y_predict数据类型不匹配的问题(相关搜索:机器学习)
  • ¥15 PB中矩阵文本型数据的总计问题。