0

A Quest After Perspectives

 3 years ago
source link: https://iphysresearch.github.io/blog/post/programing/python/modulo_on_negative/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Python 中负数取余问题

The modulo operation (%) on negative numbers in Python

Last updated on Feb 15, 2021

2 min read

Tutorial

Credit by Herb

最近发现在 Scipy 信号处理的原代码中,可以利用对负数取余的便利操作,进一步优化和清晰我们数据处理的过程。

“The % symbol in Python is called the Modulo Operator. It returns the remainder of dividing the left hand operand by right-hand operand. It’s used to get the remainder of a division problem.” — freeCodeCamp

官方 Python 文档中对 % 或者完全等价的 operator.mod() (需要import operator) 介绍不清楚,可以参考下面三个材料,写的非常好!

上面,是我搜集了 3 个与 % 相关的讲的非常详细细致的教程帖子。下面,我直接简明扼要的介绍这个 “负数取余” 的 trick。


12 % 5, -12 % 5
# output
# (2, 3)

这是为什么呢?

在数学里,“负数取余"遵循的是:

如果 ad 是整数,d 非零,那么余数 r 满足 a = q * d + r, q 为整数,且 0 <= |r| < |d|

由此可见,我们的被除数 a = 12, 我们的商 d = 5,那么有两个余 r 满足条件,分别是一个负的余数 r1 = -2 和正的余数 r2 = 3,并且总有规律 r1 + r2 = d

在计算机语言中,同号的整数运算,所有语言都遵循尽量让商小的原则,所以 12 mod 5-12 mod -5 是一样的方式,结果差一个符号,分别是 2-2。但是在异号的整数运算中,CJava 都是尽可能让商 d 更大 1(例如 -12 mod 5 的结果对应的是商 d = -2,余 r = -2),而 Python 则是会让商尽可能的小(例如 -12 mod 5 的结果对应的是商 d = -3,余 r = 3)。


最近,在我阅读 scipy/signal/spectral.py源代码时,看到在数据处理中使用“负数取余”可以写出更加简洁和清晰的代码。由此,进而可以给出如下的一种更好的理解方式:

还是 -12 mod 5 这个例子:

3tmgSb64JQM5Gkv.png

所以,有时候我们为了对时序数据计算 padding 等问题的时候,可以考虑令其数据长度为负,再整除以 step 后,来计算“余出”部分的数据长度,而不是“欠余”部分的数据长度。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK