【问题标题】:golang overflow int64 with operating directly but not with assigned a value beforehand? [duplicate]golang溢出int64直接操作但没有事先赋值? [复制]
【发布时间】:2018-05-03 02:31:13
【问题描述】:
func main() {
   var a = math.MaxInt64
   fmt.Println(a + 1)             //-9223372036854775808
   fmt.Println(math.MaxInt64 + 1) //constant 9223372036854775808 overflows int
}

why the two ways perform differently?

【问题讨论】:

  • 让你运行你的程序,它给两个溢出错误
  • 一个是常量,另一个是变量。一个在编译时评估,另一个在运行时评估。在博客中了解 Go 中的常量。

标签: go overflow int64


【解决方案1】:

在第二个示例中,math.MaxInt64 + 1 是一个常量表达式,并在编译时计算。 spec 说:

常量表达式总是被精确计算;中间值和常量本身可能需要比语言中任何预声明类型支持的精度大得多的精度。

但是,当表达式的值传递给fmt.Println 时,它必须转换为真正的预声明类型,在本例中为int,它表示为有符号的 64 位整数,无法表示常数。

常量可以通过常量声明或转换显式地赋予类型,或者在用于变量声明或赋值或作为表达式中的操作数时隐式赋予类型。如果常量值不能表示为相应类型的值,则会出错。

在第一个示例中,a + 1 不是常量表达式,而是正常的算术运算,因为 a 被声明为变量,因此常量表达式 math.MaxInt64 被转换为 int。同理:

var a int = math.MaxInt64

普通算术允许溢出:

对于有符号整数,操作 +、-、*、/ 和

只需稍作修改,您就可以使示例相同:

func main() {
    const a = math.MaxInt64
    fmt.Println(a + 1)             //constant 9223372036854775808 overflows int
    fmt.Println(math.MaxInt64 + 1) //constant 9223372036854775808 overflows int
}

【讨论】:

  • 很好的答案@caleb!很好的解释和参考。我学到了一些东西。
【解决方案2】:

它显示一个错误,因为如果您检查1 的常量值的类型,它将显示您实际上是在将int 添加到int64 值。所以首先声明一个 int64 类型的变量,然后像这样添加到const math.MaxInt64

package main

import (
    "fmt"
    "math"
)

func main() {
   var a int64 = 1 
   fmt.Println(math.MaxInt64 + a)             //-9223372036854775808
   fmt.Printf("%#T", 1)
   //fmt.Println(math.MaxInt64 + 1) //constant 9223372036854775808 overflows 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 2020-11-11
    • 2021-11-23
    • 2017-10-30
    • 2015-03-21
    • 2018-06-15
    相关资源
    最近更新 更多