2013-03-17 67 views
3

F#中是否有數據類型可以讓我計算一個浮點數到任意/大數小數位?類似於BigInt的浮點數。F#中是否存在任意精度浮點數?像BigFloat的東西?

我想這樣做

myLargeFloat = 1.0/7.0 
printfn "%12.500f" myLargeFloat // get the recurring cycle "0.142857142857142857...<500 digits long>" 

我用的是BigInt有由分子,象這樣一個BIGINT相乘得到的精度。

myLargeFloat = (bigint.Pow(10I,500)/7I) 

有沒有更好的方法來做到這一點?

回答

3

BigRational在F#動力組的定義是這樣的:

[<CustomEquality; CustomComparison>] 
    [<StructuredFormatDisplay("{StructuredDisplayString}N")>] 
    type BigRational = 
     | Z of BigInteger 
     | Q of BigRationalLarge 

BigRationalLarge被定義爲:

[<CustomEquality; CustomComparison>] 
type BigRationalLarge = 
    | Q of BigInteger * BigInteger 

要打印帶1000精度BigInt做這樣的事情:

let factorial n = Seq.fold (*) 1I [1I .. n] 

printf "Factorial of 1000 is %A" (factorial 1000I) 

Taken從here

望着BigRationalLarge類型here

有多種方式將其轉換爲不同類型的打印:

static member ToDouble(n:BigRational) = 
     match n with 
     | Z z -> ToDoubleI z 
     | Q q -> BigRationalLarge.ToDouble q 

    static member ToBigInt(n:BigRational) = 
     match n with 
     | Z z -> z 
     | Q q -> BigRationalLarge.integer q 

    static member ToInt32(n:BigRational) = 
     match n with 
     | Z z -> ToInt32I(z) 
     | Q q -> ToInt32I(BigRationalLarge.integer q) 

轉換爲雙看起來像這樣:

static member ToDouble (Q(p,q)) = 
     ToDoubleI p/ToDoubleI q 

打印它作爲分子和分母組合的默認方式:

override n.ToString() = 
     let (Q(p,q)) = n 
     if q.IsOne then p.ToString() 
     else p.ToString() + "/" + q.ToString() 

沒有真正幫助我們獲得更多的精度。在指定要打印的小數位數時,無法打印它。

因此,要回答你的問題:

你可以做,打印您需要的值的函數,使用BigRational兩個BigInt部分或者你可以寫一個全新的類型爲你做這個,但是有現在不是這樣的。

2

有一個在F# PowerPack一個BigRational類型。另請參見http://tomasp.net/blog/powerpack-numeric.aspx

+1

那麼,我該如何打印出小數點呢? printf「%A」打印出1/7,printf「%12.500f」表示BigRational類型與浮點數不兼容。 – Chaitanya 2013-03-17 11:46:58

+0

@Chaitanya從引用的博客文章中,您只需將其轉換爲像這樣浮動:'float myBigRational' – mydogisbox 2013-03-17 13:15:51

+2

但是,將其轉換爲浮動值會立即導致其失去精度。當我做'讓input1 = 1N/7N 讓輸入2 =浮動輸入1 printfn「%12.500f」input2'它打印出0.142857142857143000000000000 ...' – Chaitanya 2013-03-17 13:30:10

1

如果你真的需要任意精度浮點數,你必須使用@ mydogisbox的方法。如果您只需要比float(即System.Double)更好的精度,則可以嘗試使用decimal類型;它是System.Decimal的別名,它是128位二進制編碼的十進制(BCD)的.NET實現。它比float精確得多,但也要慢得多(如10-20x)。