根据二进制大小的不同,每种有符号整数和无符号整数类型所代表的整数范围也不尽相同,如下表所示:
func main() {
var a, b int = 7, 2
fmt.Println(a + b)
fmt.Println(a - b)
fmt.Println(a * b)
fmt.Println(a / b)
}
注意Go中当两个整数不能整除时,只保留商数,因此7/2返回的值为3
如果变量的整数类型不一致,则系统会返回异常,举例如下:
func main() {
var a int8 = 1
var b uint8 = 1
fmt.Println(a + b)
}
这里变量a的数据类型为int8,而b的数据类型为uint8,两者无法做任何运算。
如果数字超出了数据类型对应的整数范围,则系统也会返回异常,举例如下:
func main() {
var a int8 = 256
fmt.Println(a)
}
这里变量a的值256超出了int8对应的支持范围(-128到127)。
如果使用简短格式声明整数变量,则该整数变量的类型为int,大小视CPU的类型为32bits或者64bits。举例如下:
func main() {
a := 10
fmt.Printf("%T\n", a)
}
另外也可以使用整数类型相关的函数将一个类型的整数转换成另一个类型的整数,如下所示:
func main() {
a := 10 //此时a为int类型的整数
b := uint32(a) //将a转换为uint32类型的整数
c := int8(a) //将a转换为int8类型的整数
fmt.Println(b, c)
fmt.Printf("%T\n", a)
fmt.Printf("%T\n", b)
fmt.Printf("%T\n", c)
}
输出:
func main() {
var f1 float32 = 16777216
fmt.Println(f1 == f1+1)
var f2 float64 = 16777216
fmt.Println(f2 == f2+1)
}
输出:
这里我们用float32和float64分别创建了两个变量f1和f2,它们的值都为16777216(整数同样可以赋值给浮点数类型的变量),但是如果给它们各自加上1后再用==做判断,可以看到类型为float32的变量f1 == f1+1返回了布尔值true,类型为float64的变量f2 == f2+1返回了布尔值false。其原因是因为在IEEE 754标准中,32位的浮点数其构成为:
Value = (sign ? -1 : +1) * 2^exponent * (1.0 + mantissa)
可以看到16777216对应的是224,如果用float32来表示的话:
因此Value = (+1) x 224 x (1.0 + .0) = 16777216
再来看16777217,也就是224+1:
由此可以看出float32能精确表示的正整数并不是很大,所以通常我们用float64来声明浮点数变量。不过使用float64也就意味着程序会占用更大的内存,在深度学习这种需要大使用数据集的领域,占用内存的多少会对系统运行效率有较为明显的影响。
整数转换为字符串大致有三种方法:
func main() {
num := 100
fmt.Println(string(num))
}
输出:
可以看到对整数100使用string()并未将其转化为字符串形式的整数"100",而是该整数对应的字符"d"。
然后编辑器里面已经明显的提示我需要使用哪个函数去实现转换了
如果你的目的是将一个整数转换为该整数的字符串形式,则需要使用strconv.ItoA()或者strconv.Format(),举例如下:
func main() {
num := 100
fmt.Println(strconv.Itoa(num))
fmt.Println(strconv.FormatInt(int64(num), 10))
}
输出:
其中strconv.Itoa()函数里的Itoa是Integer to ASCII的缩写,
strconv包下的Itoa()是最简易也最常用的将整数转换为字符串的函数,推荐使用。
而与strconv.Itoa()相对应的则是strconv.Atoi(),即ASCII to Integer,表示将字符串转换为整数。
strconv.FormatInt()函数比较严格,要使用的话必须传入两个参数,
且第一个参数必须为int64的有符号整数,因为我们创建的变量的数据类型为int,不是int64,因此需要用int64(num)将其转化为int64才能作为合法的参数传入。
第二个参数为进制,这里的10表示十进制,如果想用十六进制表达的话,则将10改为16即可
先举例讲讲strconv.Atoi()
func main() {
str := "100"
fmt.Println(strconv.Atoi(str))
}
输出:
这里可以看到,对字符串变量str使用strconv.Atoi()后,返回的值为100
再看一下strconv.Atoi()的语法:
再来看strconv.ParseInt()的使用:
func main() {
str := "100"
fmt.Println(strconv.ParseInt(str, 10, 64))
}
输出:
可以看到,strconv.ParseInt()需要传入三个参数,
一个参数为要被转换为整数的字符串,
第二个参数为进制,这里的10代表十进制,
第三个参数代表的是bitSize, 其作用是用来指定我们想将字符串转换为哪类的有符号整数类型,其取值范围为0,8,16,32,64,分别表示int, int8, int16,int32和int64。
Strconv.FormatInt()和strconv.ParseInt()功能比较强大,但是使用起来稍微有些繁琐,明显strconv.Itoa()和strconv.Atoi()更易用。实际上strconv.Itoa()和strconv.Atoi()其实分别调用了strconv.Format()和strconv.ParseInt(),是后两者的简化版
另外Format和Parse其实是两组相反的方法,除了strconv.FormatInt()和strconv.ParseInt()外还有如下很多种类似的函数:
Format组:
FormatBool()
FormatFloat()
FormatInt()
FormatUint()
Parse组:
ParseBool()
ParseFloat()
ParseInt()
ParseUint()
总体来说,Format组是将其他数据类型转变成字符串,而Parse组是将字符串转为其他数据类型。
转载至: 网络工程师的Golang之路 -- Go数据类型(数字型) - 知乎 (zhihu.com)