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

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

a, b := 2147483647, 2147483647
c := a + b

如何有效地判断c是否溢出?

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

推荐答案

例如,要检测用于加法的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)
    }
}

输出:

integer overflow 2147483327 2147483327 0

Go相关问答推荐

无法找到与golang、nginx和postquist进行的docker-compose./主要

SEARCH On Conflict Clause不考虑乐观锁定版本

使用Gorm创建自定义连接表

如何在另一个文件夹中使用Delve运行二进制文件?

Zitadel示例Go Webapp加密密钥

Golang Viper:如果第一个字段不存在,如何从另一个字段获取值

你能把用户界面文件中的GTK4应用程序窗口添加到GTK4应用程序中吗?

通过代理从golang连接到ftp

Golang Gorm Fiber / argon2.Config 未定义

Go:如何在不加载正文的情况下创建 http 代理通行证

函数实现接口时的模式名称是什么?

确保 Go 1.20 编译时的严格可比性?

如何在切片增长时自动将切片的新元素添加到函数参数

如何使用带有方法的字符串枚举作为通用参数?

go-libp2p - 从流中接收字节

查找、解析和验证邮箱地址

通过 golang 中的 gremlin-go 库嵌入 gremlin 服务器

Golang grpc go.mod 问题

Golang prometheus 显示自定义指标

每 N 秒运行一次函数,上下文超时