前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 语言基础入门教程 —— 数据类型篇:浮点型与复数类型

Go 语言基础入门教程 —— 数据类型篇:浮点型与复数类型

作者头像
学院君
发布2019-08-08 10:03:03
1.6K0
发布2019-08-08 10:03:03
举报
文章被收录于专栏:学院君的专栏

浮点型

浮点型也叫浮点数,用于表示包含小数点的数据,比如 3.141.00 都是浮点型数据。

浮点数的表示

和 PHP 一样,Go 语言中的浮点数采用IEEE-754 标准的表达方式,定义了两个类型:float32float64,其中 float32 等价于 PHP 的 float 类型(单精度浮点数),可以精确到小数点后 7 位,float64 等价于 PHP 的 double 类型(双精度浮点数),可以精确到小数点后 15 位。

在 Go 语言里,定义一个浮点数变量的代码如下:

代码语言:javascript
复制
var float_value_1 float32

float_value_1 = 10
float_value_2 := 10.0 // 如果不加小数点,float_value_2 会被推导为整型而不是浮点型
float_value_3 := 1.1E-10

对于浮点类型需要被自动推导的变量,其类型将被自动设置为 float64,而不管赋值给它的数字是否是用 32 位长度表示的。因此,对于以上的例子,下面的赋值将导致编译错误:

代码语言:javascript
复制
float_value_1 = float_value_2  // float_value_2 是 float64 类型

编译错误信息如下:

代码语言:javascript
复制
cannot use float_value_2 (type float64) as type float32 in assignment

必须使用这样的强制类型转换才可以:

代码语言:javascript
复制
float_value_1 = float32(float_value_2)

在实际开发中,应该尽可能地使用 float64 类型,因为 math 包中所有有关数学运算的函数都会要求接收这个类型。

浮点数的精度

浮点数不是一种精确的表达方式,因为二进制无法精确表示所有十进制小数,比如 0.10.7 这种,下面我们通过一个示例来给大家直观演示下:

代码语言:javascript
复制
float_value_4 := 0.1
float_value_5 := 0.7
float_value_6 := float_value_4 + float_value_5

注:浮点数的运算和整型一样,也要保证操作数的类型一致,float32float64 类型数据不能混合运算,需要手动进行强制转化才可以,这一点和 PHP 不一样。

你觉得上面计算结果 float_value_6 的值是多少?0.8?不,它的结果是 0.7999999999999999,这是因为计算机底层将十进制的 0.10.7 转化为二进制表示时,会丢失精度,所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。

浮点数的比较

浮点数支持通过算术运算符进行四则运算,也支持通过比较运算符进行比较(前提是运算符两边的操作数类型一致),但是涉及到相等的比较除外,因为我们上面提到,看起来相等的两个十进制浮点数,在底层转化为二进制时会丢失精度,因此不能被表象蒙蔽。

如果一定要判断相等,下面是一种替代的解决方案:

代码语言:javascript
复制
p := 0.00001
// 判断 float_vlalue_1 与 float_value_2 是否相等
if math.Dim(float64(float_value_1), float_value_2) < p {
    fmt.Println("float_value_1 和 float_value_2 相等")
} 

可以看到,我们的解决方案是一种近似判断,通过一个可以接受的最小误差值 p,约定如果两个浮点数的差值在此精度的误差范围之内,则判定这两个浮点数相等。这个解决方案也是其他语言判断浮点数相等所采用的通用方案,PHP 也是这么做的。

复数类型

除了整型和浮点型之外,Go 语言还支持复数类型,与复数相对,我们可以把整型和浮点型这种日常比较常见的数字称为实数,复数是实数的延伸,可以通过两个实数(在计算机中用浮点数表示)构成,一个表示实部(real),一个表示虚部(imag),常见的表达形式如下:

代码语言:javascript
复制
z = a + bi

其中 a、b 均为实数,i 称为虚数单位,当 b = 0 时,z 就是常见的实数,当 a = 0 而 b ≠ 0 时,将 z 称之为纯虚数,如果你理解数学概念中的复数概念,这些都很好理解,下面我们来看下复数在 Go 语言中的表示和使用。

在 Go 语言中,复数支持两种类型:complex64(32位实部和虚部) 和 complex128(64位实部与虚部),对应的表示示例如下,和数学概念中的复数表示形式一致:

代码语言:javascript
复制
var complex_value_1 complex64        

complex_value_1 = 1.10 + 10i          // 由两个 float32 实数构成的复数类型
complex_value_2 := 1.10 + 10i         // 和浮点型一样,默认自动推导的实数类型是 float64,所以 complex_value_2 是 complex128 类型
complex_value_3 := complex(1.10, 10)  // 与 complex_value_2 等价

对于一个复数 z = complex(x, y),就可以通过 Go 语言内置函数 real(z) 获得该复数的实部,也就是 x,通过 imag(z) 获得该复数的虚部,也就是 y

复数支持和其它数字类型一样的算术运算符。当你使用 == 或者 != 对复数进行比较运算时,由于构成复数的实数部分也是浮点型,需要注意对精度的把握。

更多关于复数的函数,请查阅 math/cmplx 标准库的文档。如果你对内存的要求不是特别高,最好使用 complex128作为计算类型,因为相关函数大都使用这个类型的参数。

号外:Go 语言研习社

昨天新建了一个「Go 语言研习社」,用于探讨交流 Go 语言学习和使用过程中的问题,免费加入,感兴趣的、或者正在学习 Go 语言的同学可以进来看看:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客书房 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 浮点型
    • 浮点数的表示
      • 浮点数的精度
        • 浮点数的比较
        • 复数类型
        • 号外:Go 语言研习社
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档