【问题标题】:F#: integer (%) integer - Is Calculated How?F#: integer (%) integer - 是如何计算的?
【发布时间】:2016-06-21 06:48:22
【问题描述】:

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

let rec gcd = function
| (0,n) -> n
| (m,n) -> gcd(n % m,m);;

使用这个函数,我的教科书通过执行给出了示例:

gcd(36,116);;

由于 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.

我没有得到的是这个 (%) 百分比符号/运算符或在此连接中调用的任何内容。例如,我不明白如何

116 % 36 = 8

我现在已经在脑海中转过很多次了,我想不通这怎么会变成 8?

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

【问题讨论】:

标签: math recursion f# operators modulus


【解决方案1】:

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

从正面看,您可以将% 视为除法的余数。参见例如Wikipedia on Euclidean Divison。考虑9 % 4:4 适合 9 两次。但二乘四只有八。因此,还有一个余数。

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

这是一个数学上不寻常的除法和余数定义,具有一些不好的性质。通常,在计算模n时,对输入加或减n是没有效果的。对于此运算符而言并非如此:2 % 3 不等于 (2 - 3) % 3

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

/// Euclidean remainder, the proper modulo operation
let inline (%!) a b = (a % b + b) % b

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

  • 从单个索引填充行和列时,您可以计算rowNumber = index / nColscolNumber = index % nCols。但如果indexcolNumber 可以为负数,则此映射无效,而欧几里得除法和余数仍然有效。

  • 如果您想将角度标准化为 (0, 2pi),angle %! (2. * System.Math.PI) 可以完成这项工作,而“正常”% 可能会让您头疼。

【讨论】:

  • 好的,我现在明白了!!!所以因为 36 可以进入 116 3 次,加到 108 则余数是 8!感谢所有额外的奖励信息!
  • 您的 cmets 对否定参数的行为不太正确 - 只有除数的符号很重要,除数的符号无关。
  • @kvb 感谢您的提醒!我已经纠正了这一点。自从我使用带有负输入的原始运算符以来已经太久了。但这是有道理的:至少它与有符号整数上的/ 运算符一致。 (虽然我也不知道有什么证明有用的案例。)
【解决方案2】:

只是为了帮助您将来解决类似问题:在 Xamarin Studio 和 Visual Studio 等 IDE 中,如果您将鼠标光标悬停在 % 等运算符上,您应该会得到一个工具提示,因此:

Module operator tool tip

即使你不直接理解工具提示,它也会给你一些东西给谷歌。

【讨论】:

    【解决方案3】:

    基本上,称为modulo operator 的 % 运算符会将一个数字除以另一个数字,如果它不能再除,则给出其余数字。通常,您第一次使用它来理解它是如果您想通过在 f# 中执行类似的操作来查看数字是偶数还是奇数

    let firstUsageModulo = 55 %2 =0 // false because leaves 1 not 0
    

    当它第一次离开 8 时,意味着它将 116 除以 36,最接近的整数是 8。

    【讨论】:

      【解决方案4】:

      因为

      116 / 36 = 3
      116 - (3*36) = 8
      

      【讨论】:

      • 好吧,首先 116/36 不是 3,而是 3.22222222...3.222222...*36=116。 116-116=0
      • 整数计算。
      猜你喜欢
      • 2020-01-26
      • 2017-09-30
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多