Skip to content

Commit 1d89393

Browse files
committed
docs: add aritchmetic
1 parent 5bf5cd8 commit 1d89393

5 files changed

Lines changed: 384 additions & 366 deletions

File tree

docs/arithmetic.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# Bash 的算术运算
2+
3+
## 算术表达式
4+
5+
`$((...))`语法可以进行整数的算术运算。
6+
7+
```bash
8+
$ echo $((2 + 2))
9+
4
10+
```
11+
12+
上面的例子返回了`2 + 2`的计算结果。
13+
14+
`$((...))`忽略括号内部的空格,所以下面的写法都会得到同样的结果。
15+
16+
```bash
17+
$ echo $((2+2))
18+
4
19+
$ echo $(( 2+2 ))
20+
4
21+
$ echo $(( 2 + 2 ))
22+
4
23+
```
24+
25+
这个语法结构支持的算术运算符如下。
26+
27+
- `+`:加法
28+
- `-`:减法
29+
- `*`:乘法
30+
- `/`:除法(整除)
31+
- `%`:余数
32+
- `**`:指数
33+
- `++`:自增运算(前缀或后缀)
34+
- `--`:自减运算(前缀或后缀)
35+
36+
注意,上面的除法运算符的返回结果总是整数,比如`5`除以`2`,得到的结果是`2`,而不是`2.5`
37+
38+
```bash
39+
$ echo $((5 / 2))
40+
2
41+
```
42+
43+
`++``--`作为前缀是先运算后返回值,作为后缀是先返回值后运算。
44+
45+
```bash
46+
$ i=0
47+
$ echo $i
48+
0
49+
$ echo $((i++))
50+
0
51+
$ echo $i
52+
1
53+
$ echo $((++i))
54+
2
55+
$ echo $i
56+
2
57+
```
58+
59+
上面例子中,`++`作为后缀是返回值,执行`echo`命令,再进行自增运算;作为前缀则是先进行自增运算,再返回值执行`echo`命令。
60+
61+
`$((...))`结构可以嵌套。
62+
63+
```bash
64+
$ echo $(((5**2) * 3))
65+
75
66+
# 等同于
67+
$ echo $(($((5**2)) * 3))
68+
75
69+
```
70+
71+
`$((...))`内部可以用圆括号改变运算顺序。
72+
73+
```bash
74+
$ echo $(( (2 + 3) * 4 ))
75+
20
76+
```
77+
78+
上面例子中,内部的圆括号可以让加法先于乘法执行。
79+
80+
这个语法只能计算整数,否则会报错。
81+
82+
```bash
83+
# 报错
84+
$ echo $((1.5 + 1))
85+
```
86+
87+
`$((...))`的圆括号之中,不需要在变量名之前加上`$`,不过加上也不报错。
88+
89+
```bash
90+
$ number=2
91+
$ echo $((number + 1))
92+
3
93+
```
94+
95+
`$[...]`也可以做整数运算。
96+
97+
```bash
98+
$ echo $[2+2]
99+
4
100+
```
101+
102+
## 数值的进制
103+
104+
Bash 的数值默认都是十进制,但是在算术表达式中,也可以使用其他进制。
105+
106+
- `number`:没有任何特殊表示法的数字是十进制数(以10为底)。
107+
- `0number`:八进制数。
108+
- `0xnumber`:十六进制数。
109+
- `base#number``base`进制的数。
110+
111+
下面是一些例子。
112+
113+
```bash
114+
$ echo $((0xff))
115+
255
116+
$ echo $((2#11111111))
117+
255
118+
```
119+
120+
上面例子中,`0xff`是十六进制数,`2#11111111`是二进制数。
121+
122+
## 位运算
123+
124+
`$((...))`支持以下的二进制位运算符。
125+
126+
- `<<`:位左移运算,把一个数字的所有位向左移动指定的位。
127+
- `>>`:位右移运算,把一个数字的所有位向右移动指定的位。
128+
- `&:`:位的“与”运算,对两个数字的所有位执行一个`AND`操作。
129+
- `|`:位的“或”运算,对两个数字的所有位执行一个`OR`操作。
130+
- `~`:位的“否”运算,对一个数字的所有位取反。
131+
- `!`:逻辑“否”运算
132+
- `^`:位的异或运算(exclusive or),对两个数字的所有位执行一个异或操作。
133+
- `,`:求值运算。
134+
135+
下面是左移运算符`<<`的例子。
136+
137+
```bash
138+
#! /bin/bash
139+
for ((i=0;i<4;++i)); do
140+
echo $((1 << i));
141+
done
142+
```
143+
144+
上面脚本执行后,会依次输出1、2、4、8。
145+
146+
## 逻辑运算
147+
148+
`$((...))`支持以下的逻辑运算符。
149+
150+
- `<`:小于
151+
- `>`:大于
152+
- `<=`:小于或相等
153+
- `>=`:大于或相等
154+
- `==`:相等
155+
- `!=`:不相等
156+
- `&&`:逻辑与
157+
- `||`:逻辑或
158+
- `expr1?expr2:expr3`:三元条件三元运算符。若表达式`expr1`的计算结果为非零值(算术真),则执行表达式`expr2`,否则执行表达式`expr3`
159+
160+
如果逻辑表达式为真,返回`1`,否则返回`0`
161+
162+
```bash
163+
$ echo $((3 > 2))
164+
1
165+
$ echo $(( (3 > 2) || (4 <= 1) ))
166+
1
167+
```
168+
169+
三元运算符执行一个单独的逻辑测试。它用起来类似于`if/then/else`语句。
170+
171+
```bash
172+
$ a=0
173+
$ echo $((a<1 ? 1 : 0))
174+
1
175+
$ echo $((a>1 ? 1 : 0))
176+
0
177+
```
178+
179+
上面例子中,第一个表达式为真时,返回第二个表达式的值,否则返回第三个表达式的值。
180+
181+
## 赋值运算
182+
183+
算术表达式`$((...))`可以执行赋值运算。
184+
185+
```bash
186+
$ echo $((a=1))
187+
1
188+
$ echo $a
189+
1
190+
```
191+
192+
上面例子中,`a=1`对变量`a`进行赋值。这个式子本身也是一个表达式,返回值就是等号右边的值。
193+
194+
`$((...))`支持的赋值运算符,有以下这些。
195+
196+
- `parameter = value`:简单赋值。
197+
- `parameter += value`:等价于`parameter = parameter + value`
198+
- `parameter -= value`:等价于`parameter = parameter – value`
199+
- `parameter *= value`:等价于`parameter = parameter * value`
200+
- `parameter /= value`:等价于`parameter = parameter / value`
201+
- `parameter %= value`:等价于`parameter = parameter % value`
202+
- `parameter <<= value`:等价于`parameter = parameter << value`
203+
- `parameter >>= value`:等价于`parameter = parameter >> value`
204+
- `parameter &= value`:等价于`parameter = parameter & value`
205+
- `parameter |= value`:等价于`parameter = parameter | value`
206+
- `parameter ^= value`:等价于`parameter = parameter ^ value`
207+
208+
如果在表达式内部赋值,可以放在圆括号中,否则会报错。
209+
210+
```bash
211+
$ echo $(( a<1 ? (a+=1) : (a-=1) ))
212+
```
213+
214+
## 算术条件
215+
216+
`$((...))`这个语法之中,真正的算术表达式其实是`((...))`,美元符号只是用来返回`((...))`的值。
217+
218+
在某些场合不需要返回值,这时可以直接使用`((...))`,最常见的就是`if`判断。
219+
220+
```bash
221+
if ((3 > 2)); then
222+
echo "true"
223+
fi
224+
```
225+
226+
上面代码执行后,会打印出`true`
227+
228+
注意,算术计算的结果不是`0`,表示条件为真;如果是`0`,表示条件为假。这一点与命令是否执行成功,正好相反。
229+
230+
```bash
231+
$ if ((1)); then echo "It is true."; fi
232+
It is true.
233+
$ if ((0)); then echo "It is true."; else echo "it is false."; fi
234+
It is false.
235+
```
236+
237+
上面代码中,`((1))`表示条件为真,`((0))`表示条件为假。
238+
239+
```bash
240+
$ if (( foo = 5 ));then echo "It is true."; fi
241+
It is true.
242+
```
243+
244+
上面例子中,`(( foo = 5 ))`完成了两件事情。首先把`5`赋值给变量`foo`,然后根据返回值`5`,判断条件为真。
245+

docs/condition.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,9 @@ fi
310310

311311
除了支持正则表达式,`[[ ... ]]``[ ... ]`完全一样。
312312

313-
### 算术表达式
313+
### 算术条件
314314

315-
Bash 还提供了`((...))`,用来执行算术测试。如果算术计算的结果是非零值,则表示判断成立。
315+
Bash 还提供了`((...))`作为算术条件。如果算术计算的结果是非零值,则表示判断成立。
316316

317317
```bash
318318
$ if ((1)); then echo "It is true."; fi
@@ -323,22 +323,22 @@ $
323323

324324
上面例子中,`((1))`表示判断成立,`((0))`表示判断不成立。
325325

326-
下面是用算术表达式改写的数值判断脚本
326+
下面是用算术条件改写的数值判断脚本
327327

328328
```bash
329329
#!/bin/bash
330330
# test-integer2a: evaluate the value of an integer.
331331
INT=-5
332332
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
333-
if (($INT == 0)); then
333+
if ((INT == 0)); then
334334
echo "INT is zero."
335335
else
336-
if (($INT < 0)); then
336+
if ((INT < 0)); then
337337
echo "INT is negative."
338338
else
339339
echo "INT is positive."
340340
fi
341-
if (( (($INT % 2)) == 0)); then
341+
if (( ((INT % 2)) == 0)); then
342342
echo "INT is even."
343343
else
344344
echo "INT is odd."
@@ -350,7 +350,7 @@ else
350350
fi
351351
```
352352

353-
注意,`(( ))`只处理整数。并且其中的变量
353+
只要是算术表达式,都能用于`((...))`语法,详见《Bash 的算术运算》一章。
354354

355355
### 表达式的结合
356356

docs/expansion.md

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -402,74 +402,13 @@ Tue Jan 28 00:01:13 CST 2020
402402

403403
## 算术扩展
404404

405-
`$((...))`可以扩展成整数运算的结果。
405+
`$((...))`可以扩展成整数运算的结果,详见《Bash 的算术运算》一章
406406

407407
```bash
408408
$ echo $((2 + 2))
409409
4
410410
```
411411

412-
上面的例子返回了`2 + 2`的计算结果。
413-
414-
`$((...))`忽略括号内部的空格,所以下面的写法都会得到同样的结果。
415-
416-
```bash
417-
$ echo $((2+2))
418-
4
419-
$ echo $(( 2+2 ))
420-
4
421-
$ echo $(( 2 + 2 ))
422-
4
423-
```
424-
425-
这个语法结构支持的运算符如下。
426-
427-
- `+` 加法
428-
- `-` 减法
429-
- `*` 乘法
430-
- `/` 除法
431-
- `%` 余数
432-
- `**` 指数
433-
434-
注意,上面的除法运算符的返回结果总是整数,比如`5`除以`2`,得到的结果是`2`,而不是`2.5`
435-
436-
```bash
437-
$ echo $((5/2))
438-
2
439-
```
440-
441-
`$((...))`结构可以嵌套。
442-
443-
```bash
444-
$ echo $(((5**2) * 3))
445-
75
446-
# 等同于
447-
$ echo $(($((5**2)) * 3))
448-
75
449-
```
450-
451-
这个语法只能计算整数,否则会报错。
452-
453-
```bash
454-
# 报错
455-
$ echo $((1.5 + 1))
456-
```
457-
458-
`$((...))`的圆括号之中,不需要在变量名之前加上`$`
459-
460-
```bash
461-
$ number=2
462-
$ echo $((number + 1))
463-
3
464-
```
465-
466-
`$[...]`也可以做整数运算。
467-
468-
```bash
469-
$ echo $[2+2]
470-
4
471-
```
472-
473412
## 字符类
474413

475414
`[[:class:]]`表示一个字符类,匹配某一类特定字符之中的一个。常用的字符类如下。

0 commit comments

Comments
 (0)