F#:整数(%)整数 - 计算方法如何?

Nul*_*lle 4 math recursion f# operators modulus

所以在我的教科书中有一个使用f#的递归函数的例子

let rec gcd = function
| (0,n) -> n
| (m,n) -> gcd(n % m,m);;
Run Code Online (Sandbox Code Playgroud)

使用此功能,我的教科书通过执行以下内容给出了示例

gcd(36,116);;
Run Code Online (Sandbox Code Playgroud)

并且由于m = 36而不是0,那么它的第二个句子是这样的:

gcd(116 % 36,36)
gcd(8,36)
gcd(36 % 8,8)
gcd(4,8)
gcd(8 % 4,4)
gcd(0,4) 
and now hits the first clause stating this entire thing is = 4.
Run Code Online (Sandbox Code Playgroud)

我没有得到的是这个(%)百分号/操作符或此连接中调用的任何内容.对于一个实例我不知道如何

116 % 36 = 8
Run Code Online (Sandbox Code Playgroud)

我现在已经多次转过头了,我无法想象这怎么会变成8?

我知道对于那些知道这一点的人来说这可能是一个愚蠢的问题,但我非常感谢你的帮助.

Van*_*oiy 9

%模数的可疑版本,它是整数除法的余数.

在积极的情况下,您可以将其%视为分裂的剩余部分.例如,参见Euclidean Divison的Wikipedia.考虑9 % 4:4次适合9次两次.但两次四次只有八次.因此,剩下一个.

如果存在负操作数,则%有效地忽略符号以计算余数,然后使用被除数的符号作为结果的符号.这对应于舍入为零的整数除法的余数,即-2 / 3 = 0.

这是除数和余数的数学上不寻常的定义,它具有一些不良特性.通常,在计算模n时,在输入上加n或减n不起作用.对于这个运营商来说并非如此:2 % 3不等于(2 - 3) % 3.

当存在负操作数时,我通常会定义以下内容以获得有用的余数:

/// Euclidean remainder, the proper modulo operation
let inline (%!) a b = (a % b + b) % b
Run Code Online (Sandbox Code Playgroud)

到目前为止,这个运算符对于我遇到需要模数的所有情况都是有效的,而原始数据%则不是.例如:

  • 从单个索引填充行和列时,您可以计算rowNumber = index / nColscolNumber = index % nCols.但是如果index并且colNumber可以是负数,则该映射变为无效,而欧几里德除法和余数仍然有效.

  • 如果你想将角度标准化为(0,2pi),angle %! (2. * System.Math.PI)那么这项工作是否正常,而"正常" %可能让你头疼.