master
/ 2.3 数值元算.ipynb

2.3 数值元算.ipynb @masterview markup · raw · history · blame

Notebook

数值运算

Python 内置了“+、-、*、/、//、% 和 ** ”等__数值运算操作符__,分别被用于加、减、乘、除、整除、取模和幂运算。</font>

优先级 运算 运算符 符号运算 实例(a=8, b=5) 解释
1 + a + b print(a + b) 两个数加和,13
1 - a - b print(a - b) 两个数相减,3
2 * a * b print(a * b) 两个数相乘,40
2 / a / b print(a / b) 两个数相除,1.6
2 整除 // a // b print(a // b) 两个数整除,返回整数商1
2 取模 % a % b print(a % b) 模运算,返回整除的余数3
3 取正/取负 +/- +a、-b print(+a, -b) 符号运算,返回8和-5
4 ** a ** b print(a ** b) 幂运算,32768

这里的加、减、乘、取正/取负与数学上同类运算意义相同,下面介绍其他几种运算。

  • ### 精确除法(/)

不论参与运算是数是整数还是浮点数,是正数还是负数,都直接进行除法运算,__精确除法__运算结果的类型总是__浮点数__。</font>

In [1]:
print(12 / 4)        # 精确除的结果永远为浮点数 3.0
print(-10 / 4)       # -2.5
print(37.58 / -0.5)  # -75.16
print(37.58 / 3)     # 12.526666666666666
3.0
-2.5
-75.16
12.526666666666666
  • ### 整除(//)

采用的是__向下取整__的算法得到整数结果。所谓向下取整,是在计算过程中,向__负无穷大__的方向取整。需要注意的是,当参与运算的两个操作数都是整型数字时,结果是整型;当有__浮点数__参与运算的时候,结果为__值为整数的浮点数__。</font>

In [ ]:
print(10 // 4)        # 取负无穷大方向最接近 2.5的那个整数 2
print(10.0 // 4)      # 2.0,结果为浮点类型的整数
print(-10 // 4)       # 取负无穷大方向最接近 -2.5的那个整数 -3
print(37.58 // -3.5)  # 取负无穷大方向最接近 -10.737142857142857的那个整数 -11.0
  • ### 模运算(% )

模运算数学定义如下:

a % b = a - (a // b) * b

操作数 a 和 b 可以是整数,也可以是浮点数。Python 采取的向下取整算法决定了模运算的一个规律:
__模非零时,其符号与操作数 b 相同*__

In [ ]:
print(-11 % 4)   # 输出:1
print(-11 % -4)  # 输出:-3
print(11 % 4)    # 输出:3
print(11 % -4)   # 输出:-1
print(3.5 % -2)  # 输出:-0.5
print(4 % -2)    # 输出:0

模运算在数论和程序设计中都有着广泛的应用,主要应用于具有周期性规律的场景,从奇偶数的判别到素数的判定都会用到模运算。
例如: 根据x % n结果是否为0可判定x能否被n整除;
根据 x % 2 的结果是 0 还是 1 判断整数 x 的奇偶性。
下面是一些常见的应用方式。

判断整除

a % 4 == 0 and a % 100 != 0  # 结果为True则表示a可被4整除但不能被100整除

应用:输入一个年份,判断是否闰年

In [ ]:
year = int(input())    # 输入一个整数表示年份
if year % 400 == 0 or year % 100 != 0 and year % 4 == 0:  # 如果能被400整除或是能被4整除但不能被 100整除
    print(f'{year}年是闰年')
    print("jgkd")
    
    
    
else:
    print(f'{year}年是平年')
    

判断奇偶

a % 2 == 0   # 结果为True则表示a是偶数;结果为False则表示a是奇数

应用:输出列表中的偶数

In [ ]:
score = [56,45,89,78,23,19,22]  # 一个列表
for i in score:      # 遍历列表中的数字
    if i % 2 == 0:   # 如果当前数字是偶数
        print(i)     # 输出当前数字

使结果落在某区间

a % 7   # 结果在 0, 1, 2, 3, 4, 5, 6中
a % 26  # 结果在 0, 1, 2,......24, 25中

应用: 已知2022年9月1日是星期四,输入一个日期,判断是星期几

In [ ]:
date = int(input())
day = date % 7 + 3  # 对7取模的值为0,1,2,3,4,5,6
print(f'2022年9月{date}日是星期{day}')
num = '日一二三四五六'  # 字符串,字符序号为0,1,2,3,4,5,6
print(f'2022年9月{date}日是星期{num[day]}')  # num[day]取字符串中第几个字符

应用:输入一个大写字母,输出它后面第4个大写字母

In [ ]:
letter = input()
new_letter = chr((ord(letter) - 65 + 4) % 26 + 65)   # 对7取模的值为0,1,2,3,4,5,6
print(f'{letter}后面第四个大写字母是{new_letter}')
In [ ]:
A
A后面第四个大写字母是E
Y
Y后面第四个大写字母是C
  • ### 幂运算(** )

Python 中用__双星号“\*\*”__表示幂运算,a 的b次幂的表达式是 a ** b。操作数 a 和 b 可以是整数,也可以是浮点数。</font>

In [ ]:
print(3 ** 2)      # 输出:9
print(0.5 ** 2)    # 输出:0.25
print()

a ** b 中 b 为浮点数时包含开方运算,负数开偶次方结果为复数。

In [ ]:
print(3 ** 0.5)       # 3开平发,输出:1.7320508075688772
print(8 ** (1 / 3))   # 8开立方,输出:2.0
print(2 ** 4.5)       # 等价于2的9次方再开平方,输出:22.627416997969522
print((-4) ** 0.5)    # 输出:(1.2246467991473532e-16+2j)
print(3**0.15)
  • ### 运算优先级

数学运算是用运算符将对象连接起来构成表达式来实现。

程序设计中,表达式的写法与数学中的表达式稍有不同,需要按照程序设计语言规定的表示方法进行构造,运算符的优先级由高到低排列如下表所示:</font>

序号 运算符 描述
1 () 括号表达式
2 ** 幂运算
3 +x、 -x 正、负
4 *、 / 、% 乘法、除法与取模
5 + 、- 加法与减法

特别需要注意的是,优先级相同时,除了幂运算和正、负运算的结合方向是从右向左,其他运算顺序为从左到右

在复杂表达式中适当__加括号__是较好的编程习惯,既可以确保运算按自己预定的顺序进行,又提高程序的可读性和可维护性。

In [ ]:
print(-2 ** 4)        # 幂运算优先级高于取负运算,相当于 -(2**4),输出-16
print((-2) ** 4)      # 括号改变优先级,3先取负,再进行幂运算,输出16
print(2 ** -4)        # 幂运算和取负运算均为从右向左,4先取负,再进行幂运算,输出0.0625
print(2 ** 3 ** 2)    # 幂运算从右向左,相当于2**(3**2)即2**9,输出512
print((2 ** 3) ** 2)  # 括号改变优先级,即8**2,输出64

实例: 一元二次方程求解

一元二次方程可以用求根公式进行求解。
现有一元二次方程:

$ax^2 + bx + c = 0$

当a,b,c的值分别为5,8,3时,编程求其实根。

解析:此题中,判别式 $\Delta=b^2-4ac= 8 \times 8 - 4 \times 5 \times 3 = 4 > 0$,该方程有两个不相等的实数解,可利用如下一元二次方程的求根公式进行计算。

$$x_1,x_2 =\frac{-b \pm \sqrt{b^{2} - 4ac}}{2a}$$
In [ ]:
a, b, c = 5, 8, 3  # 同步赋值,5,8,3分别赋值给a,b,c
x1 = (-b + (b * b - 4 * a * c) ** (1 / 2)) / (2 * a)
x2 = (-b - (b * b - 4 * a * c) ** (1 / 2)) / (2 * a)
# x2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) # 用0.5代替1/2
print(x1, x2)                       # 在一行内输出-0.6 -1.0,输出结果用空格分隔
print(f'x1 = {x1}, x2 = {x2}')      # 在一行内输出x1 = -0.6, x2 = -1.0

程序中将求根公式转换为程序中的表达式:

x1 = ( -b + ( b * b  4 * a * c) ** (1 / 2) ) / ( 2 * a )
x2 = ( -b - ( b * b  4 * a * c) ** (1 / 2) ) / ( 2 * a )

表达式中的乘号不可以省略,分母中的 (2 * a) 的括号不能省略,否则因乘除的优级相同,会按先后顺序进行运算,那么结果就是乘 2 再除 a。
如果一定要去掉括号的话,可以将2 * a 中的乘号改为除号(/)以保持数学上的运算顺序。
分子里 (1 / 2)的括号不可以省略,因为幂运算优先级高于除法运算,没有括号时会先计算 1 次幂,再除 2,计算顺序错误。为避免这个问题,可以将 (1 / 2) 改写为 0.5。

练一练

斐波那契数列的通项公式为:

$$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项的值,并int()取整后输出。

例如:输入12时应输出144;输入48时应输出4807526976

In [ ]:
# 在空行中补充你的代码
# 输入整数n值

# 根据公式计算第n项的值


#将计算结果取整后输出