forked from tsai/mathnet-numerics
5 changed files with 2238 additions and 2 deletions
File diff suppressed because it is too large
@ -0,0 +1,71 @@ |
|||||
|
// First version copied from the F# compiler sources |
||||
|
// https://raw.github.com/fsharp/fsharp/master/src/fsharp/FSharp.Core/math/n.fsi |
||||
|
|
||||
|
//---------------------------------------------------------------------------- |
||||
|
// Copyright (c) 2002-2012 Microsoft Corporation. |
||||
|
// |
||||
|
// This source code is subject to terms and conditions of the Apache License, Version 2.0. A |
||||
|
// copy of the license can be found in the License.html file at the root of this distribution. |
||||
|
// By using this source code in any fashion, you are agreeing to be bound |
||||
|
// by the terms of the Apache License, Version 2.0. |
||||
|
// |
||||
|
// You must not remove this notice, or any other, from this software. |
||||
|
//---------------------------------------------------------------------------- |
||||
|
|
||||
|
namespace Microsoft.FSharp.Math |
||||
|
|
||||
|
#if FX_NO_BIGINT |
||||
|
open Microsoft.FSharp.Collections |
||||
|
open Microsoft.FSharp.Core |
||||
|
|
||||
|
/// Abstract internal type |
||||
|
[<NoEquality; NoComparison>] |
||||
|
type internal BigNat |
||||
|
|
||||
|
module internal BigNatModule = |
||||
|
|
||||
|
val zero : BigNat |
||||
|
val one : BigNat |
||||
|
val two : BigNat |
||||
|
|
||||
|
val add : BigNat -> BigNat -> BigNat |
||||
|
val sub : BigNat -> BigNat -> BigNat |
||||
|
val mul : BigNat -> BigNat -> BigNat |
||||
|
val divmod : BigNat -> BigNat -> BigNat * BigNat |
||||
|
val div : BigNat -> BigNat -> BigNat |
||||
|
val rem : BigNat -> BigNat -> BigNat |
||||
|
val hcf : BigNat -> BigNat -> BigNat |
||||
|
|
||||
|
val min : BigNat -> BigNat -> BigNat |
||||
|
val max : BigNat -> BigNat -> BigNat |
||||
|
val scale : int -> BigNat -> BigNat |
||||
|
val powi : BigNat -> int -> BigNat |
||||
|
val pow : BigNat -> BigNat -> BigNat |
||||
|
|
||||
|
val IsZero : BigNat -> bool |
||||
|
val isZero : BigNat -> bool |
||||
|
val isOne : BigNat -> bool |
||||
|
val equal : BigNat -> BigNat -> bool |
||||
|
val compare : BigNat -> BigNat -> int |
||||
|
val lt : BigNat -> BigNat -> bool |
||||
|
val gt : BigNat -> BigNat -> bool |
||||
|
val lte : BigNat -> BigNat -> bool |
||||
|
val gte : BigNat -> BigNat -> bool |
||||
|
|
||||
|
val hash : BigNat -> int |
||||
|
val toFloat : BigNat -> float |
||||
|
val ofInt32 : int -> BigNat |
||||
|
val ofInt64 : int64 -> BigNat |
||||
|
val toString : BigNat -> string |
||||
|
val ofString : string -> BigNat |
||||
|
|
||||
|
val toUInt32 : BigNat -> uint32 |
||||
|
val toUInt64 : BigNat -> uint64 |
||||
|
|
||||
|
val factorial : BigNat -> BigNat |
||||
|
// val randomBits : int -> BigNat |
||||
|
val bits : BigNat -> int |
||||
|
val isSmall : BigNat -> bool (* will fit in int32 (but not nec all int32) *) |
||||
|
val getSmall : BigNat -> int32 (* get the value, if it satisfies isSmall *) |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,411 @@ |
|||||
|
// First version copied from the F# compiler sources |
||||
|
// https://raw.github.com/fsharp/fsharp/master/src/fsharp/FSharp.Core/math/z.fs |
||||
|
|
||||
|
//---------------------------------------------------------------------------- |
||||
|
// Copyright (c) 2002-2012 Microsoft Corporation. |
||||
|
// |
||||
|
// This source code is subject to terms and conditions of the Apache License, Version 2.0. A |
||||
|
// copy of the license can be found in the License.html file at the root of this distribution. |
||||
|
// By using this source code in any fashion, you are agreeing to be bound |
||||
|
// by the terms of the Apache License, Version 2.0. |
||||
|
// |
||||
|
// You must not remove this notice, or any other, from this software. |
||||
|
//---------------------------------------------------------------------------- |
||||
|
|
||||
|
#nowarn "44" // This construct is deprecated. This function is for use by compiled F# code and should not be used directly |
||||
|
namespace System.Numerics |
||||
|
|
||||
|
#if FX_NO_BIGINT |
||||
|
open Microsoft.FSharp.Collections |
||||
|
open Microsoft.FSharp.Core |
||||
|
open Microsoft.FSharp.Core.Operators |
||||
|
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators |
||||
|
open Microsoft.FSharp.Primitives.Basics |
||||
|
open Microsoft.FSharp.Math |
||||
|
open System |
||||
|
open System.Globalization |
||||
|
|
||||
|
|
||||
|
// INVARIANT: signInt = 1 or -1 |
||||
|
// value(z) = signInt * v |
||||
|
// NOTE: 0 has two repns (+1,0) or (-1,0). |
||||
|
[<Struct>] |
||||
|
[<CustomEquality; CustomComparison>] |
||||
|
[<StructuredFormatDisplay("{StructuredDisplayString}I")>] |
||||
|
type BigInteger(signInt:int, v : BigNat) = |
||||
|
|
||||
|
static let smallLim = 4096 |
||||
|
static let smallPosTab = Array.init smallLim BigNatModule.ofInt32 |
||||
|
static let one = BigInteger(1) |
||||
|
static let zero = BigInteger(0) |
||||
|
|
||||
|
static member internal nat n = |
||||
|
if BigNatModule.isSmall n && BigNatModule.getSmall n < smallLim |
||||
|
then smallPosTab.[BigNatModule.getSmall n] |
||||
|
else n |
||||
|
static member internal create (s,n) = BigInteger(s,BigInteger.nat n) |
||||
|
static member internal posn n = BigInteger(1,BigInteger.nat n) |
||||
|
static member internal negn n = BigInteger(-1,BigInteger.nat n) |
||||
|
|
||||
|
|
||||
|
member x.Sign = if x.IsZero then 0 else signInt |
||||
|
member x.SignInt = signInt |
||||
|
member internal x.V = v |
||||
|
|
||||
|
static member op_Equality (x:BigInteger, y:BigInteger) = |
||||
|
//System.Console.WriteLine("x = {0}",box x) |
||||
|
//System.Console.WriteLine("y = {0}",box y) |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> BigNatModule.equal x.V y.V // +1.xv = +1.yv iff xv = yv |
||||
|
| -1, -1 -> BigNatModule.equal x.V y.V // -1.xv = -1.yv iff xv = yv |
||||
|
| 1,-1 -> BigNatModule.isZero x.V && BigNatModule.isZero y.V // 1.xv = -1.yv iff xv=0 and yv=0 |
||||
|
| -1, 1 -> BigNatModule.isZero x.V && BigNatModule.isZero y.V // -1.xv = 1.yv iff xv=0 and yv=0 |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member op_Inequality (x:BigInteger, y:BigInteger) = not (BigInteger.op_Equality(x,y)) // CA2226: OperatorsShouldHaveSymmetricalOverloads |
||||
|
|
||||
|
static member op_LessThan (x:BigInteger, y:BigInteger) = |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> BigNatModule.lt x.V y.V // 1.xv < 1.yv iff xv < yv |
||||
|
| -1,-1 -> BigNatModule.lt y.V x.V // -1.xv < -1.yv iff yv < xv |
||||
|
| 1,-1 -> false // 1.xv < -1.yv iff 0 <= 1.xv < -1.yv <= 0 iff false |
||||
|
| -1, 1 -> not (BigNatModule.isZero x.V) || not (BigNatModule.isZero y.V) |
||||
|
// -1.xv < 1.yv |
||||
|
// (a) xv=0 and yv=0, then false |
||||
|
// (b) xv<>0, -1.xv < 0 <= 1.yv, so true |
||||
|
// (c) yv<>0, -1.xv <= 0 < 1.yv, so true |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member op_GreaterThan (x:BigInteger, y:BigInteger) = // Follow lt by +/- symmetry |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> BigNatModule.gt x.V y.V |
||||
|
| -1,-1 -> BigNatModule.gt y.V x.V |
||||
|
| 1,-1 -> not (BigNatModule.isZero x.V) || not (BigNatModule.isZero y.V) |
||||
|
| -1, 1 -> false |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member internal compare(n,nn) = if BigInteger.op_LessThan(n,nn) then -1 elif BigInteger.op_Equality(n,nn) then 0 else 1 |
||||
|
static member internal hash (z:BigInteger) = z.SignInt + BigNatModule.hash(z.V) |
||||
|
|
||||
|
override x.ToString() = |
||||
|
match x.SignInt with |
||||
|
| 1 -> BigNatModule.toString x.V // positive |
||||
|
| -1 -> |
||||
|
if BigNatModule.isZero x.V |
||||
|
then "0" // not negative infact, but zero. |
||||
|
else "-" + BigNatModule.toString x.V // negative |
||||
|
| _ -> invalidOp "signs should be +/- 1" |
||||
|
|
||||
|
member x.StructuredDisplayString = x.ToString() |
||||
|
|
||||
|
interface System.IComparable with |
||||
|
member this.CompareTo(obj:obj) = |
||||
|
match obj with |
||||
|
| :? BigInteger as that -> BigInteger.compare(this,that) |
||||
|
| _ -> invalidArg "obj" "the objects are not comparable" |
||||
|
|
||||
|
override this.Equals(obj) = |
||||
|
match obj with |
||||
|
| :? BigInteger as that -> BigInteger.op_Equality(this, that) |
||||
|
| _ -> false |
||||
|
|
||||
|
override x.GetHashCode() = BigInteger.hash(x) |
||||
|
|
||||
|
|
||||
|
new (n:int) = |
||||
|
if n>=0 |
||||
|
then BigInteger (1,BigInteger.nat(BigNatModule.ofInt32 n)) |
||||
|
elif (n = System.Int32.MinValue) |
||||
|
then BigInteger(-1,BigInteger.nat(BigNatModule.ofInt64 (-(int64 n)))) |
||||
|
else BigInteger(-1,BigInteger.nat(BigNatModule.ofInt32 (-n))) |
||||
|
|
||||
|
|
||||
|
new (n:int64) = |
||||
|
if n>=0L |
||||
|
then BigInteger(1,BigInteger.nat (BigNatModule.ofInt64 n)) |
||||
|
elif (n = System.Int64.MinValue) |
||||
|
then BigInteger(-1,BigInteger.nat (BigNatModule.add (BigNatModule.ofInt64 System.Int64.MaxValue) BigNatModule.one) ) |
||||
|
else BigInteger(-1,BigInteger.nat (BigNatModule.ofInt64 (-n))) |
||||
|
|
||||
|
static member One = one |
||||
|
static member Zero = zero |
||||
|
static member (~-) (z:BigInteger) = BigInteger.create(-1 * z.SignInt,z.V) |
||||
|
static member Scale(k,z:BigInteger) = |
||||
|
if k<0 |
||||
|
then BigInteger.create(-z.SignInt, (BigNatModule.scale (-k) z.V)) // k.zsign.zv = -zsign.(-k.zv) |
||||
|
else BigInteger.create(z.SignInt, (BigNatModule.scale k z.V)) // k.zsign.zv = zsign.k.zv |
||||
|
|
||||
|
// Result: 1.nx - 1.ny (integer subtraction) |
||||
|
static member internal subnn (nx,ny) = |
||||
|
if BigNatModule.gte nx ny |
||||
|
then BigInteger.posn (BigNatModule.sub nx ny) // nx >= ny, result +ve, +1.(nx - ny) |
||||
|
else BigInteger.negn (BigNatModule.sub ny nx) // nx < ny, result -ve, -1.(ny - nx) |
||||
|
|
||||
|
static member internal addnn (nx,ny) = |
||||
|
BigInteger.posn (BigNatModule.add nx ny) // Compute "nx + ny" to be integer |
||||
|
|
||||
|
member x.IsZero = BigNatModule.isZero x.V // signx.xv = 0 iff xv=0, since signx is +1,-1 |
||||
|
member x.IsOne = (x.SignInt = 1) && BigNatModule.isOne x.V // signx.xv = 1 iff signx = +1 and xv = 1 |
||||
|
static member (+) (x:BigInteger,y:BigInteger) = |
||||
|
if y.IsZero then x else |
||||
|
if x.IsZero then y else |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> BigInteger.addnn(x.V,y.V) // 1.xv + 1.yv = (xv + yv) |
||||
|
| -1,-1 -> -(BigInteger.addnn(x.V,y.V)) // -1.xv + -1.yv = -(xv + yv) |
||||
|
| 1,-1 -> BigInteger.subnn (x.V,y.V) // 1.xv + -1.yv = (xv - yv) |
||||
|
| -1, 1 -> BigInteger.subnn(y.V,x.V) // -1.xv + 1.yv = (yv - xv) |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member (-) (x:BigInteger,y:BigInteger) = |
||||
|
if y.IsZero then x else |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> BigInteger.subnn(x.V,y.V) // 1.xv - 1.yv = (xv - yv) |
||||
|
| -1,-1 -> BigInteger.subnn(y.V,x.V) // -1.xv - -1.yv = (yv - xv) |
||||
|
| 1,-1 -> BigInteger.addnn(x.V,y.V) // 1.xv - -1.yv = (xv + yv) |
||||
|
| -1, 1 -> -(BigInteger.addnn(x.V,y.V)) // -1.xv - 1.yv = -(xv + yv) |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member ( * ) (x:BigInteger,y:BigInteger) = |
||||
|
if x.IsZero then x |
||||
|
elif y.IsZero then y |
||||
|
elif x.IsOne then y |
||||
|
elif y.IsOne then x |
||||
|
else |
||||
|
let m = (BigNatModule.mul x.V y.V) |
||||
|
BigInteger.create (x.SignInt * y.SignInt,m) // xsign.xv * ysign.yv = (xsign.ysign).(xv.yv) |
||||
|
|
||||
|
static member DivRem (x:BigInteger,y:BigInteger,rem:BigInteger byref) = |
||||
|
let d,r = BigNatModule.divmod x.V y.V |
||||
|
// HAVE: |x| = d.|y| + r and 0 <= r < |y| |
||||
|
// HAVE: xv = d.yv + r and 0 <= r < yv |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> rem <- BigInteger.posn r ; BigInteger.posn d // 1.xv = 1.d.( 1.yv) + ( 1.r) |
||||
|
| -1,-1 -> rem <- BigInteger.negn r ; BigInteger.posn d // -1.xv = 1.d.(-1.yv) + (-1.r) |
||||
|
| 1,-1 -> rem <- BigInteger.posn r ; BigInteger.negn d // 1.xv = -1.d.(-1.yv) + ( 1.r) |
||||
|
| -1, 1 -> rem <- BigInteger.negn r ; BigInteger.negn d // -1.xv = -1.d.( 1.yv) + (-1.r) |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member (/) (x:BigInteger,y:BigInteger) = |
||||
|
let mutable rem = new BigInteger(0) |
||||
|
BigInteger.DivRem(x,y,&rem) |
||||
|
static member (%) (x:BigInteger,y:BigInteger) = |
||||
|
let mutable rem = new BigInteger(0) |
||||
|
BigInteger.DivRem(x,y,&rem) |> ignore ; rem |
||||
|
static member GreatestCommonDivisor (x:BigInteger,y:BigInteger) = BigInteger.posn (BigNatModule.hcf x.V y.V) // hcf (xsign.xv,ysign.yv) = hcf (xv,yv) |
||||
|
|
||||
|
member x.IsNegative = x.SignInt = -1 && not (x.IsZero) // signx.xv < 0 iff signx = -1 and xv<>0 |
||||
|
member x.IsPositive = x.SignInt = 1 && not (x.IsZero) // signx.xv > 0 iff signx = +1 and xv<>0 |
||||
|
static member Abs (x:BigInteger) = if x.SignInt = -1 then -x else x |
||||
|
|
||||
|
static member op_LessThanOrEqual (x:BigInteger,y:BigInteger) = |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> BigNatModule.lte x.V y.V // 1.xv <= 1.yv iff xv <= yv |
||||
|
| -1,-1 -> BigNatModule.lte y.V x.V // -1.xv <= -1.yv iff yv <= xv |
||||
|
| 1,-1 -> BigNatModule.isZero x.V && BigNatModule.isZero y.V // 1.xv <= -1.yv, |
||||
|
// (a) if xv=0 and yv=0 then true |
||||
|
// (b) otherwise false, only meet at zero. |
||||
|
|
||||
|
| -1, 1 -> true // -1.xv <= 1.yv, true |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member op_GreaterThanOrEqual (x:BigInteger,y:BigInteger) = // Follow lte by +/- symmetry |
||||
|
match x.SignInt,y.SignInt with |
||||
|
| 1, 1 -> BigNatModule.gte x.V y.V |
||||
|
| -1,-1 -> BigNatModule.gte y.V x.V |
||||
|
| 1,-1 -> true |
||||
|
| -1, 1 -> BigNatModule.isZero x.V && BigNatModule.isZero y.V |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
|
||||
|
static member Pow (x:BigInteger,y:int32) = |
||||
|
if y < 0 then invalidArg "y" "The input must be non-negative." |
||||
|
let yval = BigInteger(y) |
||||
|
BigInteger.create ((if BigNatModule.isZero (BigNatModule.rem yval.V BigNatModule.two) then 1 else x.SignInt), BigNatModule.pow x.V yval.V) |
||||
|
|
||||
|
static member op_Explicit (x:BigInteger) = |
||||
|
let u = BigNatModule.toUInt32 x.V |
||||
|
if u <= uint32 System.Int32.MaxValue then |
||||
|
// Handle range [-MaxValue,MaxValue] |
||||
|
x.SignInt * int32 u |
||||
|
elif x.SignInt = -1 && u = uint32 (System.Int32.MaxValue + 1) then |
||||
|
//assert(System.Int32.MinValue = 0 - System.Int32.MaxValue - 1) |
||||
|
// Handle MinValue = -(MaxValue+1) special case not covered by the above |
||||
|
System.Int32.MinValue |
||||
|
else |
||||
|
raise (System.OverflowException()) |
||||
|
|
||||
|
static member op_Explicit (x:BigInteger) = |
||||
|
let u = BigNatModule.toUInt64 x.V |
||||
|
if u <= uint64 System.Int64.MaxValue then |
||||
|
(* Handle range [-MaxValue,MaxValue] *) |
||||
|
int64 x.SignInt * int64 u |
||||
|
elif x.SignInt = -1 && u = uint64 (System.Int64.MaxValue + 1L) then |
||||
|
//assert(System.Int64.MinValue = 0 - System.Int64.MaxValue - 1L) |
||||
|
(* Handle MinValue = -(MaxValue+1) special case not covered by the above *) |
||||
|
System.Int64.MinValue |
||||
|
else |
||||
|
raise (System.OverflowException()) |
||||
|
|
||||
|
static member op_Explicit (x:BigInteger) = |
||||
|
match x.SignInt with |
||||
|
| 1 -> BigNatModule.toFloat x.V // float (1.xv) = float (xv) |
||||
|
| -1 -> - (BigNatModule.toFloat x.V) // float (-1.xv) = - float (xv) |
||||
|
| _ -> invalidArg "x" "signs should be +/- 1" |
||||
|
|
||||
|
static member Parse(text:string) = |
||||
|
let len = text.Length |
||||
|
if len = 0 then raise (new System.FormatException("The value could not be parsed")) |
||||
|
if text.[0..0] = "-" then |
||||
|
BigInteger.negn (BigNatModule.ofString text.[1..len-1]) |
||||
|
else |
||||
|
BigInteger.posn (BigNatModule.ofString text) |
||||
|
|
||||
|
member internal x.IsSmall = BigNatModule.isSmall (x.V) |
||||
|
static member Factorial (x:BigInteger) = |
||||
|
if x.IsNegative then invalidArg "x" "The input must be non-negative." |
||||
|
if x.IsPositive then BigInteger.posn (BigNatModule.factorial x.V) |
||||
|
else BigInteger.One |
||||
|
|
||||
|
static member ( ~+ )(n1:BigInteger) = n1 |
||||
|
|
||||
|
static member FromInt64(x:int64) = new BigInteger(x) |
||||
|
static member FromInt32(x:int32) = new BigInteger(x) |
||||
|
#endif |
||||
|
|
||||
|
namespace Microsoft.FSharp.Core |
||||
|
|
||||
|
|
||||
|
type bigint = System.Numerics.BigInteger |
||||
|
|
||||
|
open System |
||||
|
open System.Diagnostics.CodeAnalysis |
||||
|
open System.Globalization |
||||
|
open Microsoft.FSharp.Core.Operators |
||||
|
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators |
||||
|
open System.Numerics |
||||
|
|
||||
|
#if FX_NO_BIGINT |
||||
|
// FxCop suppressions |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_Division(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_GreaterThan(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_GreaterThanOrEqual(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_LessThan(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_LessThanOrEqual(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_UnaryNegation(System.Numerics.BigInteger)")>] |
||||
|
[<assembly: SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Scope="member", Target="System.Numerics.BigInteger.#op_UnaryPlus(System.Numerics.BigInteger)")>] |
||||
|
do() |
||||
|
#endif |
||||
|
|
||||
|
[<AutoOpen>] |
||||
|
module NumericLiterals = |
||||
|
|
||||
|
module NumericLiteralI = |
||||
|
|
||||
|
let tab64 = new System.Collections.Generic.Dictionary<int64,obj>() |
||||
|
let tabParse = new System.Collections.Generic.Dictionary<string,obj>() |
||||
|
|
||||
|
let FromInt64Dynamic (x64:int64) : obj = |
||||
|
lock tab64 (fun () -> |
||||
|
let mutable res = Unchecked.defaultof<_> |
||||
|
let ok = tab64.TryGetValue(x64,&res) |
||||
|
if ok then res else |
||||
|
res <- BigInteger(x64) |
||||
|
tab64.[x64] <- res |
||||
|
res) |
||||
|
|
||||
|
let inline get32 (x32:int32) = FromInt64Dynamic (int64 x32) |
||||
|
|
||||
|
let inline isOX s = not (System.String.IsNullOrEmpty(s)) && s.Length > 2 && s.[0] = '0' && s.[1] = 'x' |
||||
|
|
||||
|
let FromZero () : 'T = |
||||
|
(get32 0 :?> 'T) |
||||
|
|
||||
|
let FromOne () : 'T = |
||||
|
(get32 1 :?> 'T) |
||||
|
|
||||
|
let FromInt32 (i:int32): 'T = |
||||
|
(get32 i :?> 'T) |
||||
|
|
||||
|
let FromInt64 (i:int64): 'T = |
||||
|
(FromInt64Dynamic i :?> 'T) |
||||
|
|
||||
|
let getParse s = |
||||
|
lock tabParse (fun () -> |
||||
|
let mutable res = Unchecked.defaultof<_> |
||||
|
let ok = tabParse.TryGetValue(s,&res) |
||||
|
if ok then |
||||
|
res |
||||
|
else |
||||
|
#if FSHARP_CORE_PORTABLE |
||||
|
// SL5 (and therefore Portable Profile47) does not have Parse, so make our own simple implementation |
||||
|
let parse(s : string) = |
||||
|
// ws* sign? digits+ ws* |
||||
|
let mutable i = 0 |
||||
|
// leading whitespace |
||||
|
while i < s.Length && System.Char.IsWhiteSpace(s.[i]) do |
||||
|
i <- i + 1 |
||||
|
if i = s.Length then |
||||
|
raise <| new System.ArgumentException() |
||||
|
// optional sign |
||||
|
let mutable isNegative = false |
||||
|
if s.[i] = '+' then |
||||
|
i <- i + 1 |
||||
|
elif s.[i] = '-' then |
||||
|
isNegative <- true |
||||
|
i <- i + 1 |
||||
|
if i = s.Length then |
||||
|
raise <| new System.ArgumentException() |
||||
|
// digits |
||||
|
let startDigits = i |
||||
|
while i < s.Length && System.Char.IsDigit(s.[i]) do |
||||
|
i <- i + 1 |
||||
|
let endDigits = i |
||||
|
let len = endDigits - startDigits |
||||
|
if len = 0 then |
||||
|
raise <| new System.ArgumentException() |
||||
|
// trailing whitespace |
||||
|
while i < s.Length && System.Char.IsWhiteSpace(s.[i]) do |
||||
|
i <- i + 1 |
||||
|
if i <> s.Length then |
||||
|
raise <| new System.ArgumentException() |
||||
|
// text is now valid, parse it |
||||
|
let mutable r = new System.Numerics.BigInteger(int(s.[startDigits]) - int('0')) |
||||
|
let ten = new System.Numerics.BigInteger(10) |
||||
|
for j in startDigits+1 .. endDigits-1 do |
||||
|
r <- r * ten |
||||
|
r <- r + new System.Numerics.BigInteger(int(s.[j]) - int('0')) |
||||
|
if isNegative then |
||||
|
r <- new System.Numerics.BigInteger(0) - r |
||||
|
r |
||||
|
let v = parse s |
||||
|
#else |
||||
|
let v = |
||||
|
#if FX_NO_BIGINT |
||||
|
BigInteger.Parse s |
||||
|
#else |
||||
|
#if FX_NO_BIGINT_CULTURE_PARSE |
||||
|
BigInteger.Parse s |
||||
|
#else |
||||
|
if isOX s then |
||||
|
BigInteger.Parse (s.[2..],NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture) |
||||
|
else |
||||
|
BigInteger.Parse (s,NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture) |
||||
|
#endif |
||||
|
#endif |
||||
|
#endif |
||||
|
res <- v |
||||
|
tabParse.[s] <- res |
||||
|
res) |
||||
|
|
||||
|
let FromStringDynamic (s:string) : obj = |
||||
|
getParse s |
||||
|
|
||||
|
let FromString (s:string) : 'T = |
||||
|
(FromStringDynamic s :?> 'T) |
||||
|
|
||||
|
|
||||
|
|
||||
@ -0,0 +1,124 @@ |
|||||
|
// First version copied from the F# compiler sources |
||||
|
// https://raw.github.com/fsharp/fsharp/master/src/fsharp/FSharp.Core/math/z.fsi |
||||
|
|
||||
|
//---------------------------------------------------------------------------- |
||||
|
// Copyright (c) 2002-2012 Microsoft Corporation. |
||||
|
// |
||||
|
// This source code is subject to terms and conditions of the Apache License, Version 2.0. A |
||||
|
// copy of the license can be found in the License.html file at the root of this distribution. |
||||
|
// By using this source code in any fashion, you are agreeing to be bound |
||||
|
// by the terms of the Apache License, Version 2.0. |
||||
|
// |
||||
|
// You must not remove this notice, or any other, from this software. |
||||
|
//---------------------------------------------------------------------------- |
||||
|
|
||||
|
namespace System.Numerics |
||||
|
#if FX_NO_BIGINT |
||||
|
|
||||
|
open System |
||||
|
open Microsoft.FSharp.Collections |
||||
|
open Microsoft.FSharp.Core |
||||
|
|
||||
|
/// The type of arbitrary-sized integers |
||||
|
[<Struct>] |
||||
|
[<CustomEquality; CustomComparison>] |
||||
|
type BigInteger = |
||||
|
/// Return the sum of two big integers |
||||
|
static member ( + ) : x:BigInteger * y:BigInteger -> BigInteger |
||||
|
/// Return the modulus of big integers |
||||
|
static member ( % ) : x:BigInteger * y:BigInteger -> BigInteger |
||||
|
/// Return the product of big integers |
||||
|
static member ( * ) : x:BigInteger * y:BigInteger -> BigInteger |
||||
|
/// Return the difference of two big integers |
||||
|
static member ( - ) : x:BigInteger * y:BigInteger -> BigInteger |
||||
|
/// Return the ratio of two big integers |
||||
|
static member ( / ) : x:BigInteger * y:BigInteger -> BigInteger |
||||
|
/// Return the negation of a big integer |
||||
|
static member (~-) : x:BigInteger -> BigInteger |
||||
|
/// Return the given big integer |
||||
|
static member (~+) : x:BigInteger -> BigInteger |
||||
|
/// Convert a big integer to a floating point number |
||||
|
static member op_Explicit : x:BigInteger -> float |
||||
|
/// Convert a big integer to a 64-bit signed integer |
||||
|
static member op_Explicit : x:BigInteger -> int64 |
||||
|
/// Convert a big integer to a 32-bit signed integer |
||||
|
static member op_Explicit : x:BigInteger -> int32 |
||||
|
/// Parse a big integer from a string format |
||||
|
static member Parse : text:string -> BigInteger |
||||
|
/// Return the sign of a big integer: 0, +1 or -1 |
||||
|
member Sign : int |
||||
|
/// Compute the ratio and remainder of two big integers |
||||
|
static member DivRem : x:BigInteger * y:BigInteger * rem:BigInteger byref -> BigInteger |
||||
|
|
||||
|
/// This operator is for consistency when this type be used from other CLI languages |
||||
|
static member op_LessThan : x:BigInteger * y:BigInteger -> bool |
||||
|
/// This operator is for consistency when this type be used from other CLI languages |
||||
|
static member op_LessThanOrEqual : x:BigInteger * y:BigInteger -> bool |
||||
|
/// This operator is for consistency when this type be used from other CLI languages |
||||
|
static member op_GreaterThan : x:BigInteger * y:BigInteger -> bool |
||||
|
/// This operator is for consistency when this type be used from other CLI languages |
||||
|
static member op_GreaterThanOrEqual : x:BigInteger * y:BigInteger -> bool |
||||
|
/// This operator is for consistency when this type be used from other CLI languages |
||||
|
static member op_Equality : x:BigInteger * y:BigInteger -> bool |
||||
|
/// This operator is for consistency when this type be used from other CLI languages |
||||
|
static member op_Inequality : x:BigInteger * y:BigInteger -> bool |
||||
|
|
||||
|
/// Return the greatest common divisor of two big integers |
||||
|
static member GreatestCommonDivisor : x:BigInteger * y:BigInteger -> BigInteger |
||||
|
/// Return n^m for two big integers |
||||
|
static member Pow : x:BigInteger * y:int32 -> BigInteger |
||||
|
/// Compute the absolute value of a big integer |
||||
|
static member Abs : x:BigInteger -> BigInteger |
||||
|
/// Get the big integer for zero |
||||
|
static member Zero : BigInteger |
||||
|
/// Get the big integer for one |
||||
|
static member One : BigInteger |
||||
|
|
||||
|
/// Return true if a big integer is 'zero' |
||||
|
member IsZero : bool |
||||
|
/// Return true if a big integer is 'one' |
||||
|
member IsOne : bool |
||||
|
interface System.IComparable |
||||
|
override Equals : obj -> bool |
||||
|
override GetHashCode : unit -> int |
||||
|
override ToString : unit -> string |
||||
|
|
||||
|
/// Construct a BigInteger value for the given integer |
||||
|
new : x:int -> BigInteger |
||||
|
/// Construct a BigInteger value for the given 64-bit integer |
||||
|
new : x:int64 -> BigInteger |
||||
|
#if SILVERLIGHT |
||||
|
/// Provides custom formatting for BigInteger values |
||||
|
member StructuredDisplayString : string // This needs to be accessible in order for formatting code to invoke it via reflection in Silverlight. |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
namespace Microsoft.FSharp.Core |
||||
|
|
||||
|
type bigint = System.Numerics.BigInteger |
||||
|
|
||||
|
[<AutoOpen>] |
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
module NumericLiterals = |
||||
|
|
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
module NumericLiteralI = |
||||
|
open System.Numerics |
||||
|
|
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
val FromZero : value:unit -> 'T |
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
val FromOne : value:unit -> 'T |
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
val FromInt32 : value:int32 -> 'T |
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
val FromInt64 : value:int64 -> 'T |
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
val FromString : text:string -> 'T |
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
val FromInt64Dynamic : value:int64 -> obj |
||||
|
/// Provides a default implementations of F# numeric literal syntax for literals fo the form 'dddI' |
||||
|
val FromStringDynamic : text:string -> obj |
||||
|
|
||||
|
|
||||
Loading…
Reference in new issue