[英]F# Square Root on Int
我在F#中構建一個程序,我需要在其中執行整數值的平方根。 我搜索並發現沒有允許在不使用cast int -> float
情況下執行此操作的函數。
是否有一個函數允許在沒有不必要的強制轉換的情況下生成整數的平方根?
如果你只是想要一個取整數並將其平方根作為浮點返回的函數,那么使用float
函數將int轉換為浮點然后調用sqrt
是要走的路:
sqrt (float n)
原則上,F#可以隱式允許這種轉換,但我認為它不會這樣做,因為它不清楚整數的平方根應該是什么(如注釋中所討論的)。 在C#中,您可以編寫Math.Sqrt(n)
,但這是有效的,因為C#允許在程序中的任何位置從int
到float
進行隱式轉換。
如果你想要一個平方根,如果整數返回整數,那么沒有標准的方法(如評論中所討論的那樣),所以由你來實現你需要的功能。
我很難理解為什么對int
輸入的限制,但如果這很重要,可以采用分而治之的算法。 這比使用硬件浮點的任何CPU架構上的sqrt (float n)
慢得多。
let isqrt n =
let rec loop b e =
let i = (b + e) >>> 1
let i2 = i*i
if i2 = n then
i
else
let nb, ne =
if i2 > n then
b, i
else
i, e
if nb = b && ne = e then
// Check i - 1 and i + 1 to see if either is a better fit than i
let imin = i - 1
let imax = i + 1
let i2min = imin*imin
let i2max = imax*imax
let d = n - i2 |> abs
let dmin = n - i2min |> abs
let dmax = n - i2max |> abs
if d < dmin && d < dmax then
i
elif dmin < dmax then
imin
else
imax
else
loop nb ne
loop 1 n
open FsCheck
let isqrtProperty n =
n > 1 ==> fun () ->
let r = isqrt n
let rmin = r - 1
let rmax = r + 1
let r2 = r*r
let rmin2 = rmin*rmin
let rmax2 = rmax*rmax
let d = n - r2 |> abs
let dmin = n - rmin2 |> abs
let dmax = n - rmax2 |> abs
r >= 0 && d <= dmin && d <= dmax
[<EntryPoint>]
let main argv =
let config = { Config.Quick with MaxTest = 10000; MaxFail = 100000 }
Check.One ("isqrt property", config, isqrtProperty)
0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.