F#中是否有数据类型可以让我计算浮点到任意/大量的小数位?像浮点数相当于BigInt。
我想做点什么
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)
有更好的方法吗?
答案 0 :(得分:3)
F#Powerpack中的BigRational定义如下:
[<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)
取自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 )
转换为double看起来像这样:
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()
这些都不能帮助我们获得更高的精确度。在指定要打印的小数位数时无法打印它。
所以回答你的问题:
您可以使用BigInt
的两个BigRational
部分创建一个打印所需值的函数,或者您可以编写一个全新的类型来为您执行此操作,但是没有现在就是这样的。
答案 1 :(得分:2)
F# PowerPack中有一个BigRational类型。另请参阅http://tomasp.net/blog/powerpack-numeric.aspx
答案 2 :(得分:1)
如果真正需要任意精度浮点数,则必须使用@ mydogisbox的方法。如果您只需要精度高于float
(即System.Double
)的内容,则可以尝试使用decimal
类型;它是System.Decimal
的别名,它是128位二进制编码十进制(BCD)的.NET实现。它比float
精确得多,但也慢得多(如10-20倍)。