上篇介绍了哪些数据类型,如何进行声明常量和变量,那么接下来进行详细学习下各个数据类型的使用!
一、整数
在go中,整数分为俩类,一个是无符号整数,即0以上数值;另一个是有符号数值,有正有负!
1. 有符号整数
类别 | 类型 | 描述 | 零值 | 示例 | 取值范围 |
---|---|---|---|---|---|
有符号整数 | int |
平台相关有符号整数(32位系统=32位,64位系统=64位) | 0 |
42 , -10 |
32位系统:-2³¹ ~ 2³¹-1 64位系统: -2⁶³ ~ 2⁶³-1 |
int8 |
8位有符号整数 | 0 |
127 , -128 |
-128 ~ 127 |
|
int16 |
16位有符号整数 | 0 |
32767 , -32768 |
-32768 ~ 32767 |
|
int32 |
32位有符号整数(别名 rune ) |
0 |
2147483647 |
-2147483648 ~ 2147483647 |
|
int64 |
64位有符号整数 | 0 |
9223372036854775807 |
看着都差不多,但是发现后边携带了8、16、32、64。
这些数值代表什么意思呢?
根据描述,可以发现是8位有符号、16位有符号… 什么意思呢?
大白话说一下这里
比如int8,这里的8代表在内存中占据8位(1字节),其中最前边的一位位符号位,代表正和负,剩下7位表式数值大小。所以对于负数,采用补码表示,其能表示的范围可以通过计算得出为 -2^7 到 2^7 - 1,即 -128 到 127。
// 整数
var a int8 = 10
fmt.Println("a=", a)
var b int8 = 128
fmt.Println("b=", b)
可以看到int8内存放不下128的数值,原理如上所述!!!
剩下的int 结尾的16、32、64数值,同理即可得出!
练习代码
// 整数
var a int8 = 10
fmt.Println("a=", a)
//var b int8 = 128 // 错误 int8内存放不下128的二进制数
//fmt.Println("b=", b)
// int16
var c int16 = 128
fmt.Println("c=", c)
// int32
var d int32 = -521
fmt.Println("d=", d)
// int64
var e int64 = 521
fmt.Println("e=", e)
// int
// 操作系统为32位,int为32位 即: int32
// 操作系统为64位,int为64位 即: int64
var f int = 521
fmt.Println("f=", f)
2. 无符号位
类别 | 类型 | 描述 | 零值 | 示例 | 取值范围 |
---|---|---|---|---|---|
无符号整数 | uint |
平台相关无符号整数(大小同 int ) |
0 |
100 |
32位系统:0 ~ 2³²-1 64位系统: 0 ~ 2⁶⁴-1 |
uint8 |
8位无符号整数(别名 byte ) |
0 |
255 , 0x0A |
0 ~ 255 |
|
uint16 |
16位无符号整数 | 0 |
65535 |
0 ~ 65535 |
|
uint32 |
32位无符号整数 | 0 |
4294967295 |
0 ~ 4294967295 |
|
uint64 |
64位无符号整数 | 0 |
18446744073709551615 |
0 ~ 18446744073709551615 |
|
uintptr |
无符号整数,用于存储指针地址 | 0 |
系统内存地址 | 足够存储指针值的整数 |
有了上边的知识后,我们再来验证下
用uint8为例,8位都是数值位,没有符号,也就是说没有负数!算一下能表示的范围可以通过计算得出为0到 2^8 - 1,即0 ~ 255。
练习代码
// 无符号整数
// uint8
//var g uint8 = -1
//var g uint8 = 256
var g uint8 = 255
fmt.Println("g=", g)
// uint16
var h uint16 = 521
fmt.Println("h=", h)
// uint32
var i uint32 = 521
fmt.Println("i=", i)
// uint64
var j uint64 = 521
fmt.Println("j=", j)
// uint 和int类似
// 操作系统为32位,int为32位 即: int32
// 操作系统为64位,int为64位 即: int64
var k uint = 521
fmt.Println("k=", k)
二、浮点型
浮点型分为了单精度float32和float64,这俩个都是有符号位的。
比如:float32类型,二进制内存分布
32位二进制 = 1 位用于符号位 + 8 位用于指数部分 + 剩下的 23 位用于尾数部分
32位内存分布如下图
浮点型最需要注意的是精度,而精度由尾数部分决定小数精度,23 位二进制数对应的十进制有效数字位数大约在 6 - 7 位左右。能比较准确地表示到小数点后第 6 位或者第 7 位,但是从第 7 位或者第 8 位开始可能会出现误差。当你对多个 float32 数进行运算时,小数精度较低的缺点可能会更明显。
接下来我们看下float64二进制内存分布
64位二进制 = 1 位用于符号位 + 11 位用于指数部分 + 剩下的 52 位用于尾数部分
52 位的尾数部分使得它可以表示更精确的小数。52位二进制转换为十进制后,它可以比较准确地表示到小数点后第 15 位或者第 16 位左右,在很多计算场景下能够提供足够的精度,尤其在科学计算、工程计算等领域,float64 凭借其较高的精度被广泛使用。
练习代码
// 浮点型
// float32
var l float32 = 3.1415926535897932384626433832
fmt.Println("l=", l)
// l= 3.1415927
// float64
var m float64 = 3.1415926535897932384626433832
fmt.Println("m=", m)
//m= 3.141592653589793
本篇说明了整数(有符号整数、无符号整数),浮点型(小数),基本覆盖文化数值范围。
附
本次作业
- 熟练使用整型、浮点型进行声明和使用
- 有一个数值,可以进行合理分配对应的数据类型(比如:int8、int16等类型)
- 知道类型后边的数值含义和进行合理使用
- 知道浮点型数据构成(符号位 + 指数部分 + 尾数部分)
- 编程中需注意浮点型精度,避免造成精度问题,计算错误 (差以毫厘,失之千里)