Browse Source

BigRational: add IsZero, IsOne, IsInteger, Reciprocal, Pow (compat with **), FromFraction

pull/202/merge
Christoph Ruegg 12 years ago
parent
commit
1ebebfb62f
  1. 48
      src/FSharp/BigRational.fs
  2. 13
      src/FSharp/BigRational.fsi
  3. 53
      src/FSharpUnitTests/BigRationalTests.fs

48
src/FSharp/BigRational.fs

@ -91,19 +91,19 @@ type BigRationalLarge (p : BigInteger, q : BigInteger) =
static member (~-) (num : BigRationalLarge) =
// still coprime, bq >= 0
BigRationalLarge (-num.Numerator, num.Denominator)
/// Return the sum of two rational numbers
static member (+) (x : BigRationalLarge, y : BigRationalLarge) =
BigRationalLarge.Normalize ((x.Numerator * y.Denominator) + (y.Numerator * x.Denominator), x.Denominator * y.Denominator)
/// Return the difference of two rational numbers
static member (-) (x : BigRationalLarge, y : BigRationalLarge) =
BigRationalLarge.Normalize ((x.Numerator * y.Denominator) - (y.Numerator * x.Denominator), x.Denominator * y.Denominator)
/// Return the product of two rational numbers
static member (*) (x : BigRationalLarge, y : BigRationalLarge) =
BigRationalLarge.Normalize (x.Numerator * y.Numerator, x.Denominator * y.Denominator)
/// Return the ratio of two rational numbers
static member (/) (x : BigRationalLarge, y : BigRationalLarge) =
BigRationalLarge.Normalize (x.Numerator * y.Denominator, x.Denominator * y.Numerator)
@ -113,7 +113,7 @@ type BigRationalLarge (p : BigInteger, q : BigInteger) =
BigRationalLarge.Normalize (num.Denominator, num.Numerator)
//
static member PowN (num : BigRationalLarge, n : int) =
static member Pow (num : BigRationalLarge, n : int) =
// p,q powers still coprime
BigRationalLarge (BigInteger.Pow (num.Numerator, n), BigInteger.Pow (num.Denominator, n))
@ -204,6 +204,24 @@ type BigRational =
| Z z -> sign z > 0
| Q q -> q.IsPositive
/// Indicates whether this number is an integer; denominator is one
member this.IsInteger =
match this with
| Z z -> true
| Q q -> q.Denominator.IsOne
/// Indicates whether this number is equal to zero.
member this.IsZero =
match this with
| Z z -> z.IsZero
| Q q -> q.Numerator.IsZero
/// Indicates whether this number is equal to one.
member this.IsOne =
match this with
| Z z -> z.IsOne
| Q q -> q.Denominator.IsOne && q.Numerator.IsOne
/// Return the sign of a rational number; 0, +1 or -1
member this.Sign =
if this.IsNegative then -1
@ -254,6 +272,12 @@ type BigRational =
/// Return the result of converting the given big integer to a rational number
static member FromBigInt x = Z x
static member FromIntFraction (numerator: int, denominator: int) =
Q (BigRationalLarge.Create (numerator, denominator))
static member FromBigIntFraction (numerator: BigInteger, denominator: BigInteger) =
Q (BigRationalLarge.Create (numerator, denominator))
/// Get zero as a rational number
static member Zero =
BigRational.FromInt 0
@ -387,13 +411,23 @@ type BigRational =
static member Abs (n : BigRational) =
if n.IsNegative then -n else n
/// Returns the multiplicative inverse of a rational number
static member Reciprocal (n) =
match n with
| Z z -> Q (BigRationalLarge.Create (BigInteger.One, z))
| Q q -> Q (BigRationalLarge.Reciprocal q)
/// Return the result of raising the given rational number to the given power
static member PowN (n, i : int) =
static member Pow (n, i : int) =
match n with
| Z z ->
Z (BigInteger.Pow (z, i))
| Q q ->
Q (BigRationalLarge.PowN (q, i))
Q (BigRationalLarge.Pow (q, i))
[<Obsolete("Use Pow instead, which is compatible with the ** operator. Will be removed in a future release.")>]
static member PowN (n, i : int) = BigRational.Pow(n, i)
/// Return the result of converting the given rational number to a floating point number
static member ToDouble (n : BigRational) =

13
src/FSharp/BigRational.fsi

@ -21,6 +21,9 @@ type BigRational =
member IsNegative: bool
member IsPositive: bool
member IsInteger: bool
member IsZero: bool
member IsOne: bool
member Numerator : BigInteger
member Denominator : BigInteger
@ -44,18 +47,24 @@ type BigRational =
static member op_LessThanOrEqual: BigRational * BigRational -> bool
static member op_GreaterThan: BigRational * BigRational -> bool
static member op_GreaterThanOrEqual: BigRational * BigRational -> bool
static member op_Explicit : BigRational -> BigInteger
static member op_Explicit : BigRational -> int
static member op_Explicit : BigRational -> float
static member Abs : BigRational -> BigRational
static member Reciprocal : BigRational -> BigRational
static member Pow : BigRational * int -> BigRational
static member PowN : BigRational * int -> BigRational
static member Parse: string -> BigRational
static member FromInt : int -> BigRational
static member FromBigInt : BigInteger -> BigRational
static member FromIntFraction : int * int -> BigRational
static member FromBigIntFraction : BigInteger * BigInteger -> BigRational
static member ToDouble: BigRational -> float
static member ToBigInt: BigRational -> BigInteger
static member ToInt32 : BigRational -> int

53
src/FSharpUnitTests/BigRationalTests.fs

@ -363,9 +363,16 @@ type BigNumType() =
Assert.AreEqual(bignum.FromInt(88), 88N)
()
[<Test>]
member this.Zero() =
Assert.AreEqual(bignum.Zero,0N)
Assert.IsTrue(bignum.Zero.IsZero)
()
[<Test>]
member this.One() =
Assert.AreEqual(bignum.One,1N)
Assert.IsTrue(bignum.One.IsOne)
()
[<Test>]
@ -376,6 +383,14 @@ type BigNumType() =
Assert.AreEqual(bignum.Parse("88"), g_normal)
()
[<Test>]
member this.Pow() =
Assert.AreEqual(bignum.Pow(100N,2), 10000N)
Assert.AreEqual(bignum.Pow(-3N,3), -27N)
Assert.AreEqual(bignum.Pow(g_zero,2147483647), 0N)
Assert.AreEqual(bignum.Pow(g_normal,0), 1N)
()
[<Test>]
member this.PowN() =
Assert.AreEqual(bignum.PowN(100N,2), 10000N)
@ -431,10 +446,6 @@ type BigNumType() =
[<Test>]
member this.Zero() =
Assert.AreEqual(bignum.Zero,0N)
()
// operator methods
[<Test>]
@ -595,6 +606,40 @@ type BigNumType() =
()
[<Test>]
member this.IsInteger() =
Assert.IsTrue(0N.IsInteger)
Assert.IsTrue(2N.IsInteger)
Assert.IsTrue(-2N.IsInteger)
Assert.IsTrue((2N-BigRational.FromInt(3)).IsInteger)
Assert.IsTrue((1N/BigRational.FromInt(2)+BigRational.FromIntFraction(3,2)).IsInteger)
Assert.IsFalse((1N/2N).IsInteger)
Assert.IsFalse((1N/BigRational.FromInt(2)+BigRational.FromIntFraction(3,3)).IsInteger)
[<Test>]
member this.IsOne() =
Assert.IsTrue(1N.IsOne)
Assert.IsTrue((2N/BigRational.FromInt(2)).IsOne)
Assert.IsTrue((2N-BigRational.FromInt(1)).IsOne)
Assert.IsFalse(0N.IsOne)
Assert.IsFalse(-1N.IsOne)
Assert.IsFalse(-2N.IsOne)
Assert.IsFalse(2N.IsOne)
[<Test>]
member this.IsZero() =
Assert.IsTrue(0N.IsZero)
Assert.IsTrue((2N-BigRational.FromInt(2)).IsZero)
Assert.IsFalse(1N.IsZero)
Assert.IsFalse(-1N.IsZero)
Assert.IsFalse(-2N.IsZero)
[<Test>]
member this.Numerator() =
Assert.AreEqual(g_positive1.Numerator, g_bigintpositive)

Loading…
Cancel
Save