diff --git a/src/FSharp/BigRational.fs b/src/FSharp/BigRational.fs index 52de3b7e..e80515b6 100644 --- a/src/FSharp/BigRational.fs +++ b/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)) + + [] + 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) = diff --git a/src/FSharp/BigRational.fsi b/src/FSharp/BigRational.fsi index bb98fec1..d22711b2 100644 --- a/src/FSharp/BigRational.fsi +++ b/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 diff --git a/src/FSharpUnitTests/BigRationalTests.fs b/src/FSharpUnitTests/BigRationalTests.fs index 376e6dbc..0eb11d34 100644 --- a/src/FSharpUnitTests/BigRationalTests.fs +++ b/src/FSharpUnitTests/BigRationalTests.fs @@ -363,9 +363,16 @@ type BigNumType() = Assert.AreEqual(bignum.FromInt(88), 88N) () + [] + member this.Zero() = + Assert.AreEqual(bignum.Zero,0N) + Assert.IsTrue(bignum.Zero.IsZero) + () + [] member this.One() = Assert.AreEqual(bignum.One,1N) + Assert.IsTrue(bignum.One.IsOne) () [] @@ -376,6 +383,14 @@ type BigNumType() = Assert.AreEqual(bignum.Parse("88"), g_normal) () + [] + 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) + () + [] member this.PowN() = Assert.AreEqual(bignum.PowN(100N,2), 10000N) @@ -431,10 +446,6 @@ type BigNumType() = - [] - member this.Zero() = - Assert.AreEqual(bignum.Zero,0N) - () // operator methods [] @@ -595,6 +606,40 @@ type BigNumType() = () + [] + 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) + + [] + 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) + + [] + 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) + [] member this.Numerator() = Assert.AreEqual(g_positive1.Numerator, g_bigintpositive)