python 中分数的余数

remainders for fractions in python

我不理解分数的余数。 1/2 的余数是 1,然后是相同分数但未简化的不同余数。

如有任何帮助,我们将不胜感激。

我可以理解3%2= 1,但我不明白下面的内容:

print(1%2)
=1

print(2%4)
=2

这些不是分数,这些是简单的余数计算(技术上,"modulo" 运算,但区别与正操作数无关)。 1 % 2 表示 "after removing all complete 2s from 1, what is left?" 2 % 4 表示 "after removing all complete 4s from 2, what is left?" 因为在这两种情况下都没有完整的 24 要删除,"what's left?"是整数。

如果您想要实际分数,the fractions module 会给您期望的结果:

from fractions import Fraction

print(Fraction(1, 2) == Fraction(2, 4))

将打印 True,因为作为 小数 数量,而不是余数计算,它们是等价的。

同样,执行真正的除法(有时)会起作用,例如:

print(1 / 2 == 2 / 4)

还打印 True。不过,在一般情况下,这不太可靠,因为 floating point math is "broken".

您要问的是 mod % 符号,它与除法 / 不同。 Mod 运算符 returns 第一个参数除以第二个参数后的余数,因此如果将 5 除以 2,则余数为 1。如果您尝试将较小的数字除以较大的数字,您会得到较小的数字 1/2 不可整除,因此余数为 1。

如果你把 20 个甜甜圈分给 3 个人,每个人得到 6 个甜甜圈,剩下 2 个甜甜圈。

如果你把 1 个甜甜圈分给 2 个人,每个人都得到 0 个甜甜圈,剩下 1 个甜甜圈

如果你把 2 个甜甜圈分给 4 个人,每个人得到 0 个甜甜圈,剩下 2 个甜甜圈

了解模运算符 % 及其镜像 // 及其用途

模运算符 % 给出除法的 余数1 % 2 就像将 1 除以 2,但停止任何进一步的计算,因为这是我们在不使用十进制表示法的情况下所能达到的极限,并保留未除以的部分(即 1)。

使用取模运算符 %,并没有在概念上考虑 1/2 等于 2/4。表达式op1 % op2op2表示的是一个取值范围,而op1表示一个值,可以归约到op1表示的范围内的值。

为了展示它在编程中的实用性,我将以棋盘为例。假设我有一个代表棋盘的一维数组。如果在我的代码中的某行我需要将正方形的数组索引(比如 23)转换为国际象棋符号(例如文件和等级 --> h6),我可以这样做......

>>> board = ['br', 'bn', 'bb', 'bq', 'bk', 'bb', 'bn', 'br', # 8
...          'bp', 'bp', 'bp', 'bp', 'bp', 'bp', 'bp', 'bp', # 7
...          None, None, None, None, None, None, None, None, # 6
...          None, None, None, None, None, None, None, None, # 5
...          None, None, None, None, None, None, None, None, # 4
...          None, None, None, None, None, None, None, None, # 3
...          'wp', 'wp', 'wp', 'wp', 'wp', 'wp', 'wp', 'wp', # 2
...          'wr', 'wn', 'wb', 'wq', 'wk', 'wb', 'wn', 'wr'] # 1
...         # a     b     c     d     e     f      g     h
>>>
>>> def position(sq_index):
...    return { 'file': sq_index % 8, 'rank': 7 - sq_index // 8 }
...
>>> position(23)
{'file': 7, 'rank': 5}
>>>
>>> def chess_notation(pos):
...     alpha = 'abcdefgh'
...     return alpha[pos['file']] + str(pos['rank'] + 1) # + 1 because ranks
...                                                      # start at 1 in 
...                                                      # notation.
...
>>> chess_notation(position(23))
'h6'

(在国际象棋中,棋盘 x 轴的列称为 'files',y 轴的行称为 'ranks')

请注意,position() 的实现中包含 sq_index % 8 ("sq_index modulo eight")以确定文件值。棋盘上的文件从 'a' 到 'h'(0 到 7 列)。如果我们从左到右数 0 到 7 的方块,我们就会到达终点,然后在下一个等级上重复我们的计数。到目前为止我们可能已经数过的方格数可能是 9,但是使用 9 % 8,我们知道我们的手指现在在 'b' 文件上 (9 % 8 = 1).

所以无论我们在0到63之间有什么索引,它都可以减少到0到7之间的值。如果索引n从0到63顺序递增,n % 8将产生0、1、2、3、4、5、6、7、0、1、2、3、..等等。

获取排名的计算是类似的操作。我们有 sq_index // 8// 运算符(或 "floor division operator")产生一个整数结果,余数被丢弃(本质上与 % 相反)。如果实现为 math.floor( 1 / 8 ),这会给出相同的结果。 // 是一个 Python 3 特征。对于 Python 3,1 / 8 产生一个浮点数结果,而 1 // 8 产生一个整数值。

所以,假设我们再次计算正方形,从 0 到 7。在每个正方形 n_sq // 8 产生相同的值,0。然后我们继续计算下一个排名,从 8 到 15。每个索引值都会产生 1(例如 11 // 8 = 1)。等等。代码中的 board 数组的排名从 8 到 1,因此要转换为正确的排名值,它是 8 - (sq_index // 8).

注意:对于 Python 2,// 运算符和 / 运算符都产生一个整数值。 Python 2 和 3 之间的这种差异可能会在迁移时造成一些混乱。