如何用运算符在 Go 中做数学计算

介绍

数字在编程中很常见。它们被用来表示一些东西,如:屏幕大小的尺寸、地理位置、金钱和积分、视频中经过的时间、游戏头像的位置、通过分配数字代码表示的颜色等等。

在编程中进行数学运算是一项重要的技能,因为你会经常与数字打交道。尽管对数学的理解肯定能帮助你成为一个更好的程序员,但它不是一个先决条件。如果你没有数学背景,试着把数学看作是完成你想实现的目标的工具,并作为提高你的逻辑思维能力的一种方式。

我们将使用 Go 中最常用的两种数字数据类型,整数和浮点数。

  • 整数是可以是正数、负数或 0 的整数(…,-101,…)。
  • 浮点数是包含小数点的实数,如 9.02.25

本教程将回顾我们在 Go 中对数字数据类型可以使用的运算符。

运算符

运算符是一个表示运算的符号或函数。例如,在数学中,加号或 + 是表示加法的运算符。

在 Go 中,我们将看到一些熟悉的运算符,这些运算符是从数学中带来的。然而,我们将使用的其他运算符是计算机编程中特有的。

下面是 Go 中与数学有关的运算符的快速参考表。在本教程中,我们将涵盖以下所有的运算。

预算符的返回

x + yxy 的总和

x - yxy 之差

-x 表示 x 为负数特性

+x' 表示 x’ 为正数特性

x * yxy 的积

x / yxy 的商

x % yx / y 的余

我们还将讨论复合赋值运算符,包括 +=*=,它们将算术运算符和 = 运算符结合起来。

加法和减法

在 Go 中,加法和减法运算符的表现与数学中一样。事实上,你可以把 Go 编程语言当作计算器来使用。

让我们看看一些例子,从整数开始:

  1. fmt.Println(1 + 5)
  1. Output
  2. 6

我们可以通过使用下面的语法来初始化变量以代表整数值,而不是直接将整数传入fmt.Println 语句:

  1. a := 88
  2. b := 103
  3. fmt.Println(a + b)
  1. Output
  2. 191

因为整数既可以是正数也可以是负数(也可以是 0),所以我们可以将一个负数与一个正数相加:

  1. c := -36
  2. d := 25
  3. fmt.Println(c + d)
  1. Output
  2. -11

浮点数的加法也类似:

  1. e := 5.5
  2. f := 2.5
  3. fmt.Println(e + f)
  1. Output
  2. 8

因为我们把两个浮点数加在一起,Go 返回了一个带有小数位的浮点数。然而,由于在这种情况下,小数位是零,fmt.Println 放弃了小数位的格式化。为了正确格式化输出,我们可以使用 fmt.Printf 和谓词 %.2f,它将格式化为两个小数位,就像这个例子:

  1. fmt.Printf("%.2f", e + f)
  1. Output
  2. 8.00

减法的语法与加法相同,只是我们将运算符从加号(+)改为减号(-):

  1. g := 75.67
  2. h := 32.0
  3. fmt.Println(g - h)
  1. Output
  2. 43.67

在 Go 中,我们只能对相同的数据类型使用运算符。我们不能把一个 int 和一个 float64 加在一起:

  1. i := 7
  2. j := 7.0
  3. fmt.Println(i + j)
  1. Output
  2. i + j (mismatched types int and float64)

试图在不相同的数据类型上使用运算符将导致编译器错误。

单项算术运算

一个单数的数学表达式只由一个成员或元素组成。在 Go 中,我们可以使用加号和减号作为与一个值配对的单一元素:返回值的特性(+),或改变值的符号(-)。

虽然不常用,但加号表示值的特性。我们可以对正值使用加号:

  1. i := 3.3
  2. fmt.Println(+i)
  1. Output
  2. 3.3

当我们使用加号与一个负值时,它也将返回该值的特性,在这种情况下它将是一个负值:

  1. j := -19
  2. fmt.Println(+j)
  1. Output
  2. -19

对于一个负值,加号会返回同样的负值。

然而,减号会改变一个数值的符号。因此,当我们传递一个正值时,我们会发现值前的减号会返回一个负值:

  1. k := 3.3
  2. fmt.Println(-k)
  1. Output
  2. -3.3

另外,当我们使用负值的减号单选运算符时,将返回一个正值:

  1. j := -19
  2. fmt.Println(-j)
  1. Output
  2. 19

由加号和减号表示的单项算术运算,在 +i 的情况下会返回值的同一性,或者像 -i 那样返回值的相反符号。

乘法和除法

像加法和减法一样,乘法和除法看起来与数学中的情况非常相似。我们在 Go 中用于乘法的符号是 *,用于除法的符号是 /

下面是一个在 Go 中对两个浮点数进行乘法的例子:

  1. k := 100.2
  2. l := 10.2
  3. fmt.Println(k * l)
  1. Output
  2. 1022.04

在 Go 中,除法有不同的特点,这取决于我们要除的数字类型。

如果我们要除以整数,Go 可以使用 / 运算符来执行除法,对于商 x,返回的数字是小于或等于 x 的最大整数。

如果你运行下面这个除法80 / 6 的例子,你会收到 13 作为输出,数据类型是int

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. m := 80
  7. n := 6
  8. fmt.Println(m / n)
  9. }
  1. Output
  2. 13

如果想要的输出是浮点数,你必须在除法之前明确地转换这些数值。

你可以用 float32()float64() 包裹你想要的浮点数类型来实现:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. s := 80
  7. t := 6
  8. r := float64(s) / float64(t)
  9. fmt.Println(r)
  10. }
  1. Output
  2. 13.333333333333334

取模

% 运算符是取模,它返回除法后的余数而不是商。这对于寻找同一数字的倍数是很有用的。

让我们看一个取模的例子:

  1. o := 85
  2. p := 15
  3. fmt.Println(o % p)
  1. Output
  2. 10

分开来看,85 除以 15 会返回 5 的商和 10 的余数。我们的程序在这里返回值 10,因为模运算符返回除法表达式的剩余部分。

要对 float64 数据类型进行模数计算,你将使用 math 包中的 Mod 函数:

  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. func main() {
  7. q := 36.0
  8. r := 8.0
  9. s := math.Mod(q, r)
  10. fmt.Println(s)
  11. }
  1. Output
  2. 4

运算符优先级

在 Go 中,就像在数学中一样,我们需要牢记,运算符将按照优先顺序进行评估,而不是从左到右或从右到左。

如果我们看一下下面这个数学表达式:

  1. u = 10 + 10 * 5

我们可以从左往右读,但是乘法会先进行,所以如果我们要打印 `u’,我们会收到以下数值:

  1. Output
  2. 60

这是因为 10 * 5 被计算为 50,然后我们加上 10,返回 60 作为最终结果。

如果我们想把10加到10上,然后把这个和乘以 5,我们在 Go 中使用括号,就像在数学中那样:

  1. u := (10 + 10) * 5
  2. fmt.Println(u)
  1. Output
  2. 100

记住操作顺序的一个方法是通过缩写 PEMDAS

字母顺序代表的是

1 P Parentheses 括号

2 E Exponent 指数

3 M Multiplication 乘法

4 D Division 除法

5 A Addition 加法

6 S Subtraction 减法

你可能熟悉另一个关于运算顺序的缩写,如 BEDMASBODMAS。无论哪种缩写对你来说都是有效的,在 Go 中进行数学运算时,尽量记住它,以便返回你所期望的结果。

赋值运算符

最常见的赋值运算符是你已经使用过的:等号 == 赋值运算符将右边的值分配给左边的变量。例如,v = 23 将整数 23 的值分配给变量 v

在编程时,通常使用复合赋值运算符,对一个变量的值进行运算,然后将得到的新值赋给该变量。这些复合运算符将一个算术运算符和 = 运算符结合起来。因此,对于加法,我们将 += 结合起来,得到复合运算符 +=。让我们看看这看起来像什么:

  1. w := 5
  2. w += 1
  3. fmt.Println(w)
  1. Output
  2. 6

首先,我们设置变量 w 等于 5 的值,然后我们使用 += 复合赋值运算符将右边的数字加到左边变量的值上,然后将结果赋给 w

复合赋值运算符在 for 循环的情况下经常使用,当你想重复一个过程几次时,就会用到它:

  1. package main
  2. import "fmt"
  3. func main() {
  4. values := []int{0, 1, 2, 3, 4, 5, 6}
  5. for _, x := range values {
  6. w := x
  7. w *= 2
  8. fmt.Println(w)
  9. }
  10. }
  1. Output0
  2. 2
  3. 4
  4. 6
  5. 8
  6. 10
  7. 12

通过使用 for 循环遍历名为 values 的切片,你能够自动完成 *= 运算符的过程,该运算符将变量 w 乘以数字 2,然后将结果分配回变量 w

Go 对本教程中讨论的每个算术运算符都有一个复合赋值运算符。

要添加然后赋值:

  1. y += 1

做减法,然后赋值:

  1. y -= 1

做乘法,然后再赋值:

  1. y *= 2

做除法,然后再赋值:

  1. y /= 3

取余,然后再赋值:

  1. y %= 3

当需要逐步增加或减少时,或者当你需要将程序中的某些过程自动化时,复合赋值运算符就很有用。

总结

本教程涵盖了许多你将在整数和浮点数数据类型中使用的运算符。你可以在理解 Go 的数据类型如何在 Go 中转换数据类型中了解更多关于不同的数据类型。