{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 数值运算"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">Python 内置了“+、-、*、/、//、% 和 ** ”等<font color=Red>__数值运算操作符__</font>,分别被用于加、减、乘、除、整除、取模和幂运算。</font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"| 优先级 | 运算 | 运算符 | 符号运算 | 实例(a=8, b=5) | 解释 |\n",
"| :----: | :-------: | :----: | :------: | :---------------: | :---------------------: |\n",
"| 1 | 加 | + | a + b | **print**(a + b) | 两个数加和,13 |\n",
"| 1 | 减 | - | a - b | **print**(a - b) | 两个数相减,3 |\n",
"| 2 | 乘 | * | a * b | **print**(a * b) | 两个数相乘,40 |\n",
"| 2 | 除 | / | a / b | **print**(a / b) | 两个数相除,1.6 |\n",
"| 2 | 整除 | // | a // b | **print**(a // b) | 两个数整除,返回整数商1 |\n",
"| 2 | 取模 | % | a % b | **print**(a % b) | 模运算,返回整除的余数3 |\n",
"| 3 | 取正/取负 | +/- | +a、-b | **print**(+a, -b) | 符号运算,返回8和-5 |\n",
"| 4 | 幂 | ** | a ** b | **print**(a ** b) | 幂运算,32768 |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"这里的加、减、乘、取正/取负与数学上同类运算意义相同,下面介绍其他几种运算。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 精确除法(/)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">不论参与运算是数是整数还是浮点数,是正数还是负数,都直接进行除法运算,<font color=Red>__精确除法__</font>运算结果的类型总是<font color=Red>__浮点数__</font>。</font>"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.0\n",
"-2.5\n",
"-75.16\n",
"12.526666666666666\n"
]
}
],
"source": [
"print(12 / 4) # 精确除的结果永远为浮点数 3.0\n",
"print(-10 / 4) # -2.5\n",
"print(37.58 / -0.5) # -75.16\n",
"print(37.58 / 3) # 12.526666666666666"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 整除(//)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">采用的是<font color=Red>__向下取整__</font>的算法得到整数结果。所谓向下取整,是在计算过程中,向<font color=Red>__负无穷大__</font>的方向取整。需要注意的是,当参与运算的两个操作数都是整型数字时,结果是整型;当有<font color=Red>__浮点数__</font>参与运算的时候,结果为<font color=Red>__值为整数的浮点数__</font>。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(10 // 4) # 取负无穷大方向最接近 2.5的那个整数 2\n",
"print(10.0 // 4) # 2.0,结果为浮点类型的整数\n",
"print(-10 // 4) # 取负无穷大方向最接近 -2.5的那个整数 -3\n",
"print(37.58 // -3.5) # 取负无穷大方向最接近 -10.737142857142857的那个整数 -11.0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 模运算(% )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"模运算数学定义如下:\n",
"\n",
"<center>a % b = a - (a // b) * b</center>\n",
"\n",
"操作数 a 和 b 可以是整数,也可以是浮点数。Python 采取的向下取整算法决定了模运算的一个规律: \n",
"<font color=Red>__模非零时,其符号与操作数 b 相同*__</font>。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch2/1.png\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(-11 % 4) # 输出:1\n",
"print(-11 % -4) # 输出:-3\n",
"print(11 % 4) # 输出:3\n",
"print(11 % -4) # 输出:-1\n",
"print(3.5 % -2) # 输出:-0.5\n",
"print(4 % -2) # 输出:0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"模运算在数论和程序设计中都有着广泛的应用,主要应用于具有周期性规律的场景,从奇偶数的判别到素数的判定都会用到模运算。 \n",
"例如: 根据x % n结果是否为0可判定x能否被n整除; \n",
"根据 x % 2 的结果是 0 还是 1 判断整数 x 的奇偶性。 \n",
"下面是一些常见的应用方式。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**判断整除**\n",
"```python\n",
"a % 4 == 0 and a % 100 != 0 # 结果为True则表示a可被4整除但不能被100整除\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 应用:输入一个年份,判断是否闰年"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"year = int(input()) # 输入一个整数表示年份\n",
"if year % 400 == 0 or year % 100 != 0 and year % 4 == 0: # 如果能被400整除或是能被4整除但不能被 100整除\n",
" print(f'{year}年是闰年')\n",
" print(\"jgkd\")\n",
" \n",
" \n",
" \n",
"else:\n",
" print(f'{year}年是平年')\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**判断奇偶**\n",
"```python\n",
"a % 2 == 0 # 结果为True则表示a是偶数;结果为False则表示a是奇数\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 应用:输出列表中的偶数"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"score = [56,45,89,78,23,19,22] # 一个列表\n",
"for i in score: # 遍历列表中的数字\n",
" if i % 2 == 0: # 如果当前数字是偶数\n",
" print(i) # 输出当前数字"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**使结果落在某区间**\n",
"```python\n",
"a % 7 # 结果在 0, 1, 2, 3, 4, 5, 6中\n",
"a % 26 # 结果在 0, 1, 2,......24, 25中\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 应用: 已知2022年9月1日是星期四,输入一个日期,判断是星期几"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"date = int(input())\n",
"day = date % 7 + 3 # 对7取模的值为0,1,2,3,4,5,6\n",
"print(f'2022年9月{date}日是星期{day}')\n",
"num = '日一二三四五六' # 字符串,字符序号为0,1,2,3,4,5,6\n",
"print(f'2022年9月{date}日是星期{num[day]}') # num[day]取字符串中第几个字符"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 应用:输入一个大写字母,输出它后面第4个大写字母"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"letter = input()\n",
"new_letter = chr((ord(letter) - 65 + 4) % 26 + 65) # 对7取模的值为0,1,2,3,4,5,6\n",
"print(f'{letter}后面第四个大写字母是{new_letter}')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"A\n",
"A后面第四个大写字母是E\n",
"Y\n",
"Y后面第四个大写字母是C"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 幂运算(\\*\\* )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">Python 中用<font color=Red>__双星号“\\*\\*”__</font>表示幂运算,a 的b次幂的表达式是 a \\*\\* b。操作数 a 和 b 可以是整数,也可以是浮点数。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(3 ** 2) # 输出:9\n",
"print(0.5 ** 2) # 输出:0.25\n",
"print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"a ** b 中 b 为浮点数时包含开方运算,负数开偶次方结果为复数。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(3 ** 0.5) # 3开平发,输出:1.7320508075688772\n",
"print(8 ** (1 / 3)) # 8开立方,输出:2.0\n",
"print(2 ** 4.5) # 等价于2的9次方再开平方,输出:22.627416997969522\n",
"print((-4) ** 0.5) # 输出:(1.2246467991473532e-16+2j)\n",
"print(3**0.15)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 运算优先级"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">数学运算是用运算符将对象连接起来构成表达式来实现。 \n",
"\n",
"程序设计中,表达式的写法与数学中的表达式稍有不同,需要按照程序设计语言规定的表示方法进行构造,运算符的优先级由高到低排列如下表所示:</font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"| 序号 | 运算符 | 描述 |\n",
"| :---- | :--------- | :---------------- |\n",
"| 1 | () | 括号表达式 |\n",
"| 2 | ** | 幂运算 |\n",
"| 3 | +x、 -x | 正、负 |\n",
"| 4 | \\*、 / 、% | 乘法、除法与取模 |\n",
"| 5 | + 、- | 加法与减法 |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"特别需要注意的是,**优先级相同时,除了幂运算和正、负运算的结合方向是从右向左,其他运算顺序为从左到右**。\n",
"\n",
"在复杂表达式中适当<font color=Red>__加括号__</font>是较好的编程习惯,既可以确保运算按自己预定的顺序进行,又提高程序的可读性和可维护性。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(-2 ** 4) # 幂运算优先级高于取负运算,相当于 -(2**4),输出-16\n",
"print((-2) ** 4) # 括号改变优先级,3先取负,再进行幂运算,输出16\n",
"print(2 ** -4) # 幂运算和取负运算均为从右向左,4先取负,再进行幂运算,输出0.0625\n",
"print(2 ** 3 ** 2) # 幂运算从右向左,相当于2**(3**2)即2**9,输出512\n",
"print((2 ** 3) ** 2) # 括号改变优先级,即8**2,输出64"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 实例: 一元二次方程求解"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"一元二次方程可以用求根公式进行求解。 \n",
"现有一元二次方程: \n",
"\n",
"$ax^2 + bx + c = 0$ \n",
"\n",
"当a,b,c的值分别为5,8,3时,编程求其实根。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**解析**:此题中,判别式 $\\Delta=b^2-4ac= 8 \\times 8 - 4 \\times 5 \\times 3 = 4 > 0$,该方程有两个不相等的实数解,可利用如下一元二次方程的求根公式进行计算。\n",
"\n",
"$$x_1,x_2 =\\frac{-b \\pm \\sqrt{b^{2} - 4ac}}{2a}$$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a, b, c = 5, 8, 3 # 同步赋值,5,8,3分别赋值给a,b,c\n",
"x1 = (-b + (b * b - 4 * a * c) ** (1 / 2)) / (2 * a)\n",
"x2 = (-b - (b * b - 4 * a * c) ** (1 / 2)) / (2 * a)\n",
"# x2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) # 用0.5代替1/2\n",
"print(x1, x2) # 在一行内输出-0.6 -1.0,输出结果用空格分隔\n",
"print(f'x1 = {x1}, x2 = {x2}') # 在一行内输出x1 = -0.6, x2 = -1.0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"程序中将求根公式转换为程序中的表达式:\n",
"```python\n",
"x1 = ( -b + ( b * b – 4 * a * c) ** (1 / 2) ) / ( 2 * a )\n",
"x2 = ( -b - ( b * b – 4 * a * c) ** (1 / 2) ) / ( 2 * a )\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"表达式中的乘号不可以省略,分母中的 `(2 * a)` \n",
"的括号不能省略,否则因乘除的优级相同,会按先后顺序进行运算,那么结果就是乘 2 再除 a。 \n",
"如果一定要去掉括号的话,可以将` 2 * a` 中的乘号改为除号(/)以保持数学上的运算顺序。 \n",
"分子里 `(1 / 2) `的括号不可以省略,因为幂运算优先级高于除法运算,没有括号时会先计算 1 次幂,再除 2,计算顺序错误。为避免这个问题,可以将 `(1 / 2)` 改写为 0.5。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" <font face='楷体' color='red' size=5> 练一练 </font>\n",
" \n",
" 斐波那契数列的通项公式为:\n",
" \n",
" $$a_n=\\frac{1}{\\sqrt{5}}\\left [ \\left ( \\frac{1+\\sqrt{5} }{2} \\right )^{n} - \\left ( \\frac{1-\\sqrt{5} }{2} \\right )^{n} \\right ] $$\n",
" \n",
" 输入一个整数n,计算数列第n项的值,并int()取整后输出。\n",
" \n",
" 例如:输入12时应输出144;输入48时应输出4807526976"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 在空行中补充你的代码\n",
"# 输入整数n值\n",
"\n",
"# 根据公式计算第n项的值\n",
"\n",
"\n",
"#将计算结果取整后输出\n",
"\n",
"\n",
"\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}