检测Go中的signed signed overflow溢出

d11*_*wtq 15 integer-overflow go

我正在构建一个Lisp,如果计算会导致它们溢出,我希望32位整数自动切换到64位整数.同样,对于64位溢出,切换到任意大小的整数.

我遇到的问题是我不知道检测整数溢出的"正确"方法是什么.

a, b := 2147483647, 2147483647
c := a + b
Run Code Online (Sandbox Code Playgroud)

如何有效地检查c是否溢出?

我已经考虑过总是转换为64位值来进行计算,然后在可能的情况下再次调整大小,但这对于像基本算术一样原始和核心的东西来说似乎很昂贵且内存浪费.

pet*_*rSO 9

例如,要检测32位整数溢出以进行添加,

package main

import (
    "errors"
    "fmt"
    "math"
)

var ErrOverflow = errors.New("integer overflow")

func Add32(left, right int32) (int32, error) {
    if right > 0 {
        if left > math.MaxInt32-right {
            return 0, ErrOverflow
        }
    } else {
        if left < math.MinInt32-right {
            return 0, ErrOverflow
        }
    }
    return left + right, nil
}
func main() {
    var a, b int32 = 2147483327, 2147483327
    c, err := Add32(a, b)
    if err != nil {
        // handle overflow
        fmt.Println(err, a, b, c)
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

integer overflow 2147483327 2147483327 0
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我想我可能有一个更短的解决方案,但不确定是否存在不起作用的边缘情况:`((c &lt; a) != (b &lt; 0))`,其中`c := a + b` 。 (2认同)