【问题标题】:F# Get Root of a uInt64F# 获取 uInt64 的根
【发布时间】:2020-01-05 01:55:56
【问题描述】:

如何在 F# 中对 uInt64 求平方根?

我试过了:

sqrt(1UL) // the type 'uint64' does not support the operator 'Sqrt'

//and

1UL**0.5 //the type 'uint64' does not support the operator 'Pow'

您可以使用pown 做整数指数,但不能替换sqrt,因为幂只能是整数。

pown 4 2 // 16

【问题讨论】:

  • 为什么不直接转换成double
  • 请在发帖前考虑一下您的问题。你很快就会发现你也不能取int 的平方根。它还会直接引出一个问题:intint64 的平方根有什么类型,您希望它的行为如何?
  • @CharlesRoddie 我不是函数式程序员,所以也许我没有看到你在说什么,但我绝对希望能够找到 int 的根。例如,sqrt(4) = 2sqrt(3) = 1.73...。我希望它表现得像数学函数,我输入一个数字并取出一个数字,而无需显式输入所有内容
  • @NicoSchertler 如果我没记错的话,double 是有符号的 64 位数字,uInt64 是无符号的 64 位数字。因此,我认为 uInt64 可能无法正确转换为双精度。
  • 当你说“我希望它表现得像数学函数”时,你所说的“数学函数”的类型是什么:即域和余域是什么。

标签: math f#


【解决方案1】:

如果您只想要平方根的整数部分,最好的办法是为它定义自己的函数。对于您的情况(使用无符号长值),它可能如下所示:

let rec sqrtul n =
    if n <= 0UL then 0UL else
        let r2 = (sqrtul (n >>> 2)) <<< 1
        let r3 = r2 + 1UL
        if n < r3 * r3 then r2 else r3

你可以这样称呼它:

sqrtul 1UL

可以在网上找到替代实现。

如果您的目标是在所选类型允许的范围内获得完整的十进制值,则必须首先转换初始值。例如,如果您需要浮点结果,请执行以下操作:

sqrt (float 1UL)

【讨论】:

  • 嗯。我正在寻找完整的十进制值。我觉得有趣的是输入和输出类型必须相同。可悲的是,铸造测试确实遇到了我的精度问题。正因为如此,我不愿将其标记为答案,但你超级值得这些支持
  • 如果您需要更高的精度,decimal 而不是 floatdouble 可能是要走的路。
  • 遗憾的是,十进制也不支持 sqrt
  • 我找到了用于十进制的 sqrt 的实现 stackoverflow.com/questions/4124189/…
【解决方案2】:

当我开始研究十进制 sqrt 算法时,我找到了一些答案。 Decimal 允许任意精度,因此您可以将其用于任何数字类型。

解决方案 1:通过迭代控制精度 (newton sqrt approximation)

let itrSqrt n maxIter = 
    let rec guess g i =
      match i with
      | 0 -> g
      | _ -> guess ((g + (n / g)) / 2M) (i - 1)
    guess (n / 2M) maxIter;;

解决方案 2:使用 epsilon 控制精度(意味着迭代之间的变化)(Performing Math operations on decimal datatype in C#?)

let dSqrt (d:decimal) (epsilon:decimal): decimal =
    let rec guess previous =
        if previous = 0M then 0M
        else 
            let current = (previous + d / previous) / 2M
            if(abs(previous - current) < epsilon) 
            then current
            else guess(current)
    let initialGuess = decimal (sqrt(double d))
    guess(initialGuess)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多