【问题标题】:Mod or rem. Which one to use with positive integers in Haskell?国防部或雷姆。在 Haskell 中,哪一个与正整数一起使用?
【发布时间】:2020-08-07 14:52:03
【问题描述】:

Haskell 中的 rem 的行为与 JavaScript 中的 % 类似。当使用时钟类比 rem 时,无论值是正数还是负数,总是顺时针方向。 rem 带分号

divident / divisor = quotient

Prelude> 10 `rem` 3
1

Prelude> -10 `rem` 3
-1

% 在 JavaScript 中的工作方式相同

$ node

> 10 % 3
  1

> -10 % 3
  -1

mod 的行为类似于rem,当两个值都为正时。唯一的区别是,当其中一个数字为负时,mod 在时钟上倒退,而不是顺时针方向并取除数的符号。

知道modrem 在两个数字都为正数时给出相同的结果,建议在Haskell 中使用哪一个?

【问题讨论】:

  • mod 是根据divMod 定义的defined,它是根据quotRem 定义的。 rem 是根据quotRem 定义的,所以它的函数调用少了一个。
  • 请注意-10 `rem` 3 被解析为- (10`rem`3)。这实际上并没有改变问题,但这意味着-10 `mod` 3 确实 给出-1 作为结果,而(-10)`mod`3 给出2 作为结果。
  • 另请注意,JavaScript 从 C 继承了 % 的这种行为,这可能更相关。 (同时,例如在 Python 中,% 运算符的行为类似于 Haskell 的 mod。)
  • 如果您知道这两个数字都是正数,请使用 rem,因为这是现代处理器上的指令(我只记得 NS32k 也为 mod 提供了指令)。

标签: haskell


【解决方案1】:

divmod 在语义上更敏感,而quotrem 稍微快一些。所以我的建议是使用divmod 作为反射,只有在做了很多工作以确保它们的性能实际上与某些减速相关之后才改用quotrem,你绝对必须修复并做大量工作以证明它是安全的。从长远来看,细微的符号错误几乎肯定会花费您更多的调试时间,而不是细微的性能错误会花费您的计算时间。

【讨论】:

  • 我同意mod 往往在语义上更合理,但是“细微的标志错误”通常应该被 QuickCheck 立即发现,而细微的性能错误往往根本无法修复因为它们中的每一个都不会产生足够的差异,以至于任何人都会关心这样做......而大量这样的次优可能一起使程序变得相当慢。
  • 无论如何,出于性能原因所做的任何更改都应通过基准测试进行广泛检查。例如,如果除数是已知的 2 次幂,则本机代码生成器将 divmod 优化为单次移位/和指令,而 quotrem 则为一条指令优化三个指令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
  • 2016-10-06
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多