【问题标题】:Computing remainder without using modulus operator F#不使用模运算符 F# 计算余数
【发布时间】:2016-12-17 04:28:32
【问题描述】:

我已经实现了我的代码,它基本上是在不使用模数运算符的情况下计算两个数字的余数,但是,我陷入了一种非常忙碌的情况。我知道逻辑但是我是 f# 的新手并且不知道如何实现它。

let rec modulus a b =
if b = 0 Console.WriteLine("Sorry Wrong Divisor")
let bool neg = a < 0
a = abs a
b = abs b
modulus(val-divisor,divisor)

我只知道我在这里遇到了一个非常基本的错误,任何帮助,

【问题讨论】:

  • 编写的代码很难理解。缩进不正确,我怀疑等于运算符被滥用了
  • 除了 Tomas Petricek 所指出的之外,您还创建了一个名为 neg 的值(您无需在此处说 let boollet neg = a &lt; 0 就足够了)。但是您永远不会使用该值。您可能打算在某处有一个if 声明。 F# 中的if 语句写成if (condition) then (value-if-true) else (value-if-false)。仅当 value-if-true 解析为 unit 类型时,else 才是可选的。如果您还不明白这意味着什么,请不要担心,只需记住 if 语句中的 else 部分几乎从来都不是可选的。

标签: f# c#-to-f#


【解决方案1】:

实现此功能的第一步是修复缩进并将草图转换为实际编译和运行的有效 F# 代码 - 这应该有助于您进入下一步,即修复实现的逻辑。

与您的类似并实际运行的最小代码如下所示:

let rec modulus value divisor : int =
  printfn "value=%d, divisor=%d" value divisor
  if divisor = 0 then Console.WriteLine("Sorry Wrong Divisor")
  let neg = value < 0
  let value = abs value
  let divisor = abs divisor
  modulus (value-divisor) divisor

modulus 10 5
  • 我修复了缩进 - F# 对缩进敏感,所以这很重要。
  • 我将您的 a = abs a 替换为 let - let 关键字定义了一个新变量,隐藏了现有变量(因为您无法改变现有变量 - 它们在 F# 中是不可变的)
  • 我将您的变量重命名为始终使用 divisorvalue 名称
  • 我添加了printfn,这样你就可以看到函数是如何运行的(它会进入一个无限循环,因为它目前从不检查终止条件!)
  • 我必须添加类型注释 : int 来说明结果将是 int - 因为您的函数永远不会返回,所以这是必需的(但您可以在修复此问题后将其删除)

【讨论】:

  • 非常感谢,现在一切都清楚了。是的,缩进在 F# 中非常敏感,因为没有大括号。
【解决方案2】:

你可以用更简单的方式计算模数

let modulus a b=
    if b = 0.0 then failwith "Cannot divide by zero"
    a - b * truncate(a / b);

【讨论】:

  • 我的要求是使用递归函数但是谢谢
  • 编码错误。您通常无法可靠地将浮点数与相等运算符进行比较。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-17
相关资源
最近更新 更多