Skip to content

1.go语言数字类型

go语言支持整型和浮点型数字,并且原生支持复数,其中位的运算采用补码

Go也有基于架构的类型,如:intuintuintptr

这些类型的长度都是根据运行程序所在的操作系统类型所决定的。

  • intuint在32位操作系统上,它们均使用32位(4个字节),在64位操作系统上,它们均使用64位(8个字节)。
  • uintptr的长度被设定为足够存放一个指针即可。

Go语言中没有float类型。(Go语言中只有float32float64)没有double类型。

与操作系统架构无关的类型都有固定的大小,并在类型的名称中就可以看出:

整数

  • int8(-128->127)
  • int16(-32768->32767)
  • int32(-2147483648->2147483647)
  • int64(-9223372036854775808->9223372036854775807)

无符号整数

  • uint8(0->255)
  • uint16(0->65535)
  • uint32(0->4294967295)
  • uint64(0->18446744073709551615)

浮点型(IEEE-754标准)

Go语言提供两种精度的浮点数,即float32和float64,其中float32占用4个字节大小,而float64占用8个字节大小

浮点数都是相对精准的,存在一定的误差:

float32类型的浮点数可以提供约6个十进制数的精度,即按照四舍五入法默认小数点后保留六位。

float64类型的浮点数可以提供约15个十进制数的精度,即按照四舍五入法默认小数点后保留十五位。

通常应该优先使用float64类型,因为float32类型的累计祭祀按无法很容易扩散,并且float32能精确表示正整数并不是很大

浮点型取值范围

数据类型最大值常量
float323.4e38math.MaxFloat32
float641.8e308math.MaxFloat64

高精度计算,github.com/shopspring/decimal

go
v1 := decimal.NewFromFloat(0.1)
v2 := decimal.NewFromFloat(0.2)
v3 := decimal.NewFromFloat(0.3)
fmt.Println(v1.Add(v2).Equal(v3)) // true

f1 := decimal.NewFromFloat(67.6)
f2 := decimal.NewFromFloat(100)
fmt.Println(f1.Mul(f2).IntPart()) // 6760
v1 := decimal.NewFromFloat(0.1)
v2 := decimal.NewFromFloat(0.2)
v3 := decimal.NewFromFloat(0.3)
fmt.Println(v1.Add(v2).Equal(v3)) // true

f1 := decimal.NewFromFloat(67.6)
f2 := decimal.NewFromFloat(100)
fmt.Println(f1.Mul(f2).IntPart()) // 6760

int型是计算最快的一种类型。

整型的零值为0,浮点型的零值为0.0

案例

各个数字类型的长度和取值范围

go
package main

import(
	"fmt"
	"math"
	"unsafe"
)

func main() {
    var i8 int8
    var i16 int16
    var i32 int32
    var i64 int64
    
    var ui8 uint8
    var ui16 uint16
    var ui32 uint32
    var ui64 uint64
    
    fmt.Printf("%T %dB %v~%v\n",i8, unsafe.Szieof(i8), math.MinInt8, math.MaxInt8)
    fmt.Printf("%T %dB %v~%v\n",i16, unsafe.Szieof(i16), math.MinInt8, math.MaxInt16)
    fmt.Printf("%T %dB %v~%v\n",i32, unsafe.Szieof(i32), math.MinInt8, math.MaxInt32)
    fmt.Printf("%T %dB %v~%v\n",i64, unsafe.Szieof(i64), math.MinInt8, math.MaxInt64)
    
    fmt.Printf("%T %dB %v~%v\n",ui8, unsafe.Szieof(ui8), 0, math.MaxInt8)
    fmt.Printf("%T %dB %v~%v\n",ui16, unsafe.Szieof(ui16), 0, math.MaxInt16)
    fmt.Printf("%T %dB %v~%v\n",ui32, unsafe.Szieof(ui32), 0, math.MaxInt32)
    fmt.Printf("%T %dB %v~%v\n",ui64, unsafe.Szieof(ui64), 0, math.MaxInt64)
    
    var f32 float32
    var f64 float64
    
    fmt.Printf("%T %dB %v~%v\n", f32, unsafe.Sizeof(f32), -math.MaxFloat32, math.MaxFloat32)
    fmt.Printf("%T %dB %v~%v\n", f64, unsafe.Sizeof(f64), -math.MaxFloat64, math.MaxFloat64)
    
    var ui uint
    ui = uint(math.MaxUint64) //再+1会导致overflows错误
    fmt.Printf("%T %dB %v~%v\n", ui,unsafe.Sizeof(ui), 0 , ui)
    
    var imax, imin int
    imax = int(math.MaxInt64) //再+1会导致overflows错误
    imin = int(math.MinInt64) //再-1会导致overflows错误
    
    fmt.Printf("%T %dB %v~%v\n", imax,unsafe.Sizeof(imax), imin , imax)
}
package main

import(
	"fmt"
	"math"
	"unsafe"
)

func main() {
    var i8 int8
    var i16 int16
    var i32 int32
    var i64 int64
    
    var ui8 uint8
    var ui16 uint16
    var ui32 uint32
    var ui64 uint64
    
    fmt.Printf("%T %dB %v~%v\n",i8, unsafe.Szieof(i8), math.MinInt8, math.MaxInt8)
    fmt.Printf("%T %dB %v~%v\n",i16, unsafe.Szieof(i16), math.MinInt8, math.MaxInt16)
    fmt.Printf("%T %dB %v~%v\n",i32, unsafe.Szieof(i32), math.MinInt8, math.MaxInt32)
    fmt.Printf("%T %dB %v~%v\n",i64, unsafe.Szieof(i64), math.MinInt8, math.MaxInt64)
    
    fmt.Printf("%T %dB %v~%v\n",ui8, unsafe.Szieof(ui8), 0, math.MaxInt8)
    fmt.Printf("%T %dB %v~%v\n",ui16, unsafe.Szieof(ui16), 0, math.MaxInt16)
    fmt.Printf("%T %dB %v~%v\n",ui32, unsafe.Szieof(ui32), 0, math.MaxInt32)
    fmt.Printf("%T %dB %v~%v\n",ui64, unsafe.Szieof(ui64), 0, math.MaxInt64)
    
    var f32 float32
    var f64 float64
    
    fmt.Printf("%T %dB %v~%v\n", f32, unsafe.Sizeof(f32), -math.MaxFloat32, math.MaxFloat32)
    fmt.Printf("%T %dB %v~%v\n", f64, unsafe.Sizeof(f64), -math.MaxFloat64, math.MaxFloat64)
    
    var ui uint
    ui = uint(math.MaxUint64) //再+1会导致overflows错误
    fmt.Printf("%T %dB %v~%v\n", ui,unsafe.Sizeof(ui), 0 , ui)
    
    var imax, imin int
    imax = int(math.MaxInt64) //再+1会导致overflows错误
    imin = int(math.MinInt64) //再-1会导致overflows错误
    
    fmt.Printf("%T %dB %v~%v\n", imax,unsafe.Sizeof(imax), imin , imax)
}

二进制、八进制或16进制浮点数的格式定义数字

go
package main

import "fmt"

func main() {
    //十进制
    var a int = 10
    fmt.Printf("%d \n",a) //10
    fmt.Printf("%b \n",a) //1010 占位符%b表示二进制
    
    //八进制以 0开头
    var b int = 077
    fmt.Printf("%o \n", b)
    
    //16进制,以0x开头
    var c int = 0xff
    fmt.Printf("%x \n" , c) //ff
    fmt.Printf("%X \n" , c) //FF
    
}
package main

import "fmt"

func main() {
    //十进制
    var a int = 10
    fmt.Printf("%d \n",a) //10
    fmt.Printf("%b \n",a) //1010 占位符%b表示二进制
    
    //八进制以 0开头
    var b int = 077
    fmt.Printf("%o \n", b)
    
    //16进制,以0x开头
    var c int = 0xff
    fmt.Printf("%x \n" , c) //ff
    fmt.Printf("%X \n" , c) //FF
    
}

浮点型

go
package main

import (
	"fmt"
    "math"
)

func main() {
    fmt.Printf("%f \n", math.Pi)
    fmt.Printf("%.2f \n", math.Pi)
}
package main

import (
	"fmt"
    "math"
)

func main() {
    fmt.Printf("%f \n", math.Pi)
    fmt.Printf("%.2f \n", math.Pi)
}

复数

go
var c1 complex64
c1 = 1 + 2i

var c2 complex128
c2 = 2 + 3i

fmt.Printf(c1)
fmt.Printf(c2)
var c1 complex64
c1 = 1 + 2i

var c2 complex128
c2 = 2 + 3i

fmt.Printf(c1)
fmt.Printf(c2)

复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部和虚部为64

https://www.bilibili.com/video/BV1zR4y1t7Wj?p=14&spm_id_from=pageDriver&vd_source=271cfb4bb43eae8c9b0543f4ae14ec31