13 How to Do Math in Go With Operators

如何用运算符在 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 编程语言当作计算器来使用。

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

fmt.Println(1 + 5)
Output
6

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

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

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

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

浮点数的加法也类似:

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

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

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

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

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

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

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

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

单项算术运算 #

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

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

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

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

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

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

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

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

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

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

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

乘法和除法 #

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

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

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

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

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

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

package main
    
import (
    "fmt"
)
    
func main() {
    m := 80
    n := 6
    
    fmt.Println(m / n)
}
Output
13

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

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

package main
    
import (
    "fmt"
)
    
func main() {
    s := 80
    t := 6
    r := float64(s) / float64(t)
    fmt.Println(r)
}
Output
13.333333333333334

取模 #

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

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

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

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

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

package main
    
import (
    "fmt"
    "math"
)
    
func main() {
    q := 36.0
    r := 8.0
    s := math.Mod(q, r)

    fmt.Println(s)
}
Output
4

运算符优先级 #

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

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

u = 10 + 10 * 5

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

Output
60

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

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

u := (10 + 10) * 5
fmt.Println(u)
Output
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

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

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

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

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

package main
    
import "fmt"
    
func main() {

    values := []int{0, 1, 2, 3, 4, 5, 6}
    
    for _, x := range values {

        w := x

        w *= 2

        fmt.Println(w)
    }
 }
Output0
2
4
6
8
10
12

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

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

要添加然后赋值:

y += 1

做减法,然后赋值:

y -= 1

做乘法,然后再赋值:

y *= 2

做除法,然后再赋值:

y /= 3

取余,然后再赋值:

y %= 3

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

总结 #

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