Math.NET Numerics
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

647 lines
25 KiB

// First version copied from the F# Power Pack
// https://raw.github.com/fsharp/powerpack/master/src/FSharp.PowerPack.Unittests/BigRationalTests.fs
namespace MathNet.Numerics.Tests
open MathNet.Numerics
open NUnit.Framework
open System
open System.Collections
open System.Collections.Generic
open System.Numerics
[<TestFixture>]
type public BigRationalTests() =
// BigRational Tests
// =================
// Notes: What cases to consider?
// For (p,q) cases q=0, q=1, q<>1. [UPDATE: remove (x,0)]
// For (p,q) when q=1 there could be 2 internal representations, either Z or Q.
// For (p,0) this value can be signed, corresponds to +/- infinity point. [Update: remove it]
// Hashes on (p,1) for both representations must agree.
// For binary operators, try for result with and without HCF (normalisation).
// Also: 0/0 is an acceptable representation. See normalisation code. [Update: remove it].
// Overrides to test:
// .ToString()
// .GetHashCode()
// .Equals()
// IComparable.CompareTo()
// Misc construction.
let natA n = BigRational.FromInt n // internally Z
let natB n = (natA n / natA 7) * natA 7 // internally Q
let ratio p q = BigRational.FromInt p / BigRational.FromInt q
let (/%) b c = BigRational.FromBigInt b / BigRational.FromBigInt c
// Misc test values
let q0 = natA 0
let q1 = natA 1
let q2 = natA 2
let q3 = natA 3
let q4 = natA 4
let q5 = natA 5
let minIntI = bigint System.Int32.MinValue
let maxIntI = bigint System.Int32.MaxValue
let ran = System.Random()
let nextZ n = bigint (ran.Next(n))
// A selection of test points.
let points =
// A selection of integer and reciprical points
let points =
[for i in -13I .. 13I -> i,1I] @
[for i in -13I .. 13I -> 1I,i]
// Exclude x/0
let points = [for p,q in points do if q <> 0I then yield p,q ] // PROPOSE: (q,0) never a valid Q value, filter them out of tests...
// Scale by various values, including into BigInt range
let scale (kp,kq) (p,q) = (p*kp,q*kq)
let scales k pqs = List.map (scale k) pqs
let points = List.concat [points;
scales (10000I,1I) points;
scales (1I,10000I) points;
scales (maxIntI,1I) points;
scales (1I,maxIntI) points;
]
points
let pointsNonZero = [for p,q in points do if p<>0I then yield p,q] // non zero points
let makeQs p q =
if q = 1I && minIntI <= p && p <= maxIntI then
// (p,1) where p is int32
let p32 = int32 p
[natA p32;natB p32;BigRational.FromBigInt p] // two reprs for int32
else
[BigRational.FromBigInt p / BigRational.FromBigInt q]
let miscQs = [for p,q in points do yield! makeQs p q]
let product xs ys = [for x in xs do for y in ys do yield x,y]
let vector1s = [for z in points -> z]
let vector2s = product points points
[<Test>]
member this.BasicTests1() =
check "generic format h" "1N" (sprintf "%A" 1N)
check "generic format q" "-1N" (sprintf "%A" (-1N))
test "vliwe98" (id -2N = - 2N)
test "d3oc002" (LanguagePrimitives.GenericZero<bignum> = 0N)
test "d3oc112w" (LanguagePrimitives.GenericOne<bignum> = 1N)
check "weioj3h" (sprintf "%O" 3N) "3"
check "weioj3k" (sprintf "%O" (3N / 4N)) "3/4"
check "weioj3k" (sprintf "%O" (3N / 400000000N)) "3/400000000"
check "weioj3l" (sprintf "%O" (3N / 3N)) "1"
check "weioj3q" (sprintf "%O" (-3N)) "-3"
//check "weioj3w" (sprintf "%O" -3N) "-3"
check "weioj3e" (sprintf "%O" (-3N / -3N)) "1"
// The reason why we do not use hardcoded values is the the representation may change based on the NetFx we are targeting.
// For example, when targeting NetFx4.0, the result is "-3E+61" instead of "-3000....0N"
let v = -30000000000000000000000000000000000000000000000000000000000000N
check "weioj3r" (sprintf "%O" v) ((box v).ToString())
[<Test>]
member this.BasicTests2() =
// Test arithmetic ops: tests
let test2One name f check ((p,q),(pp,qq)) =
// There may be several ways to construct the test rationals
let zs = makeQs p q
let zzs = makeQs pp qq
let results = [for z in zs do for zz in zzs do yield f (z,zz)]
let refP,refQ = check (p,q) (pp,qq)
let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ
let resOK (result:BigRational) =
result.Numerator * refQ = refP * result.Denominator &&
BigRational.Equals(refResult,result)
match List.tryFind (fun result -> not (resOK result)) results with
| None -> () // ok
| Some result -> printf "Test failed. %s (%A,%A) (%A,%A). Expected %A. Observed %A\n" name p q pp qq refResult result
reportFailure "cejkew09"
let test2All name f check vectors = List.iter (test2One name f check) vectors
// Test arithmetic ops: call
test2All "add" (BigRational.(+)) (fun (p,q) (pp,qq) -> (p*qq + q*pp,q*qq)) vector2s
test2All "sub" (BigRational.(-)) (fun (p,q) (pp,qq) -> (p*qq - q*pp,q*qq)) vector2s
test2All "mul" (BigRational.(*)) (fun (p,q) (pp,qq) -> (p*pp,q*qq)) vector2s // *) <-- for EMACS
test2All "div" (BigRational.(/)) (fun (p,q) (pp,qq) -> (p*qq,q*pp)) (product points pointsNonZero)
[<Test>]
member this.RangeTests() =
// Test x0 .. dx .. x1
let checkRange3 (x0:BigRational) dx x1 k =
let f (x:BigRational) = x * BigRational.FromBigInt k |> BigRational.ToBigInt
let rangeA = {x0 .. dx .. x1} |> Seq.map f
let rangeB = {f x0 .. f dx .. f x1}
//printf "Length=%d\n" (Seq.length rangeA)
let same = Seq.forall2 (=) rangeA rangeB
check (sprintf "Range3 %A .. %A .. %A scaled to %A" x0 dx x1 k) same true
checkRange3 (0I /% 1I) (1I /% 7I) (100I /% 1I) (7I*1I)
checkRange3 (0I /% 1I) (1I /% 7I) (100I /% 11I) (7I*11I)
checkRange3 (1I /% 13I) (1I /% 7I) (100I /% 11I) (7I*11I*13I)
for i = 0 to 1000 do
let m = 1000 // max steps is -m to m in steps of 1/m i.e. 2.m^2
let p0,q0 = nextZ m ,nextZ m + 1I
let p1,q1 = nextZ m ,nextZ m + 1I
let pd,qd = nextZ m + 1I,nextZ m + 1I
checkRange3 (p0 /% q0) (pd /% qd) (p1 /% q1) (q0 * q1 * qd)
// Test x0 .. x1
let checkRange2 (x0:BigRational) x1 =
let z0 = BigRational.ToBigInt x0
let z01 = BigRational.ToBigInt (x1 - x0)
let f (x:BigRational) = x |> BigRational.ToBigInt
let rangeA = [x0 .. x1] |> List.map f // range with each item rounded down
let rangeB = [z0 .. z0 + z01] // range of same length from the round down start point
check (sprintf "Range2: %A .. %A" x0 x1) rangeA rangeB
checkRange2 (0I /% 1I) (100I /% 1I)
checkRange2 (0I /% 1I) (100I /% 11I)
checkRange2 (1I /% 13I) (100I /% 11I)
for i = 0 to 1000 do
let m = 10000 // max steps is -m to m in steps of 1 i.e. 2.m
let p0,q0 = nextZ m ,nextZ m + 1I
let p1,q1 = nextZ m ,nextZ m + 1I
checkRange2 (p0 /% q0) (p1 /% q1) //(q0 * q1 * qd)
// ToString()
// Cases: integer, computed integer, rational<1, rational>1, +/-infinity, nan
(natA 1).ToString() |> check "ToString" "1"
(natA 0).ToString() |> check "ToString" "0"
(natA (-12)).ToString() |> check "ToString" "-12"
(natB 1).ToString() |> check "ToString" "1"
(natB 0).ToString() |> check "ToString" "0"
(natB (-12)).ToString() |> check "ToString" "-12"
(1I /% 3I).ToString() |> check "ToString" "1/3"
(12I /% 5I).ToString() |> check "ToString" "12/5"
//(13I /% 0I).ToString() |> check "ToString" "1/0" // + 1/0. Plan to make this invalid value
//(-13I /% 0I).ToString() |> check "ToString" "1/0" // - 1/0. Plan to make this invalid value
//(0I /% 0I).ToString() |> check "ToString" "0/0" // 0/0. Plan to make this invalid value
// GetHashCode
// Cases: zero, integer, computed integer, computed by multiple routes.
let checkSameHashGeneric a b = check (sprintf "GenericHash %A %A" a b) (a.GetHashCode()) (b.GetHashCode())
let checkSameHash (a:BigRational) (b:BigRational) = check (sprintf "BigRationalHash %A %A" a b) (a.GetHashCode()) (b.GetHashCode()); checkSameHashGeneric a b
List.iter (fun n -> checkSameHash (natA n) (natB n)) [-10 .. 10]
List.iter (fun n -> checkSameHash n ((n * q3 + n * q2) / q5)) miscQs
// bug 3488: should non-finite values be supported?
//let x = BigRational.FromBigInt (-1I) / BigRational.FromBigInt 0I
//let q2,q3,q5 = BigRational.FromInt 2,BigRational.FromInt 3,BigRational.FromInt 5
//let x2 = (x * q2 + x * q3) / q5
//x,x2,x = x2
// Test: Zero,One?
check "ZeroA" BigRational.Zero (natA 0)
check "ZeroA" BigRational.Zero (natA 0)
check "OneA" BigRational.One (natB 1)
check "OneB" BigRational.One (natB 1)
[<Test>]
member this.BinaryAndUnaryOperators() =
// Test: generic bop
let testR2One name f check ((p,q),(pp,qq)) =
// There may be several ways to construct the test rationals
let zs = makeQs p q
let zzs = makeQs pp qq
let resultRef = check (p,q) (pp,qq) // : bool
let args = [for z in zs do for zz in zzs do yield (z,zz)]
match List.tryFind (fun (z,zz) -> resultRef <> f (z,zz)) args with
| None -> () // ok
| Some (z,zz) -> printf "Test failed. %s (%A,%A) (%A,%A) = %s %A %A. Expected %A.\n" name p q pp qq name z zz resultRef
reportFailure "cknwe9"
// Test: generic uop
let testR1One name f check (p,q) =
// There may be several ways to construct the test rationals
let zs = makeQs p q
let resultRef = check (p,q) //: bool
match List.tryFind (fun z -> resultRef <> f z) zs with
| None -> () // ok
| Some z -> printf "Test failed. %s (%A,%A) = %s %A. Expected %A.\n" name p q name z resultRef
reportFailure "vekjkrejvre0"
let testR2All name f check vectors = List.iter (testR2One name f check) vectors
let testR1All name f check vectors = List.iter (testR1One name f check) vectors
// Test: relations
let sign (i:BigInteger) = BigInteger(i.Sign)
testR2All "=" BigRational.(=) (fun (p,q) (pp,qq) -> (p*qq = q*pp)) vector2s
testR2All "=" BigRational.op_Equality (fun (p,q) (pp,qq) -> (p*qq = q*pp)) vector2s
testR2All "!=" BigRational.op_Inequality (fun (p,q) (pp,qq) -> (p*qq <> q*pp)) vector2s
// p/q < pp/qq
// iff (p * sign q) / (q * sign q) < (pp * sign qq) / (qq * sign qq)
// iff (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q * sign q) since q*sign q is always +ve.
testR2All "<" BigRational.(<) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q * sign q)) vector2s
testR2All ">" BigRational.(>) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) > (pp * sign qq) * (q * sign q)) vector2s
testR2All "<=" BigRational.(<=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) <= (pp * sign qq) * (q * sign q)) vector2s
testR2All ">=" BigRational.(>=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) >= (pp * sign qq) * (q * sign q)) vector2s
// System.IComparable tests
let BigRationalCompareTo (p:BigRational,q:BigRational) = (p :> System.IComparable).CompareTo(q)
testR2All "IComparable.CompareTo" BigRationalCompareTo (fun (p,q) (pp,qq) -> compare ((p * sign q) * (qq * sign qq)) ((pp * sign qq) * (q * sign q))) vector2s
// Test: is negative, is positive
testR1All "IsNegative" (fun (x:BigRational) -> x.IsNegative) (fun (p,q) -> sign p * sign q = -1I) vector1s
testR1All "IsPositive" (fun (x:BigRational) -> x.IsPositive) (fun (p,q) -> sign p * sign q = 1I) vector1s
testR1All "IsZero" (fun (x:BigRational) -> x = q0) (fun (p,q) -> sign p = 0I) vector1s
let test1One name f check (p,q) =
// There may be several ways to construct the test rationals
let zs = makeQs p q
let results = [for z in zs -> f z]
let refP,refQ = check (p,q)
let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ
let resOK (result:BigRational) =
result.Numerator * refQ = refP * result.Denominator &&
BigRational.Equals(refResult,result)
match List.tryFind (fun result -> not (resOK result)) results with
| None -> () // ok
| Some result -> printf "Test failed. %s (%A,%A). Expected %A. Observed %A\n" name p q refResult result
reportFailure "klcwe09wek"
let test1All name f check vectors = List.iter (test1One name f check) vectors
test1All "neg" (BigRational.(~-)) (fun (p,q) -> (-p,q)) vector1s
test1All "pos" (BigRational.(~+)) (fun (p,q) -> (p,q)) vector1s // why have ~+ ???
// Test: Abs,Sign
test1All "Abs" (BigRational.Abs) (fun (p,q) -> (abs p,abs q)) vector1s
testR1All "Sign" (fun (x:BigRational) -> x.Sign) (fun (p,q) -> check "NonZeroDenom" (sign q <> 0I) true; (sign p * sign q) |> int32) vector1s
// Test: Pow
test1All "Pow(x,2)" (fun x -> BigRational.Pow(x,2)) (fun (p,q) -> (p*p,q*q)) vector1s
test1All "Pow(x,1)" (fun x -> BigRational.Pow(x,1)) (fun (p,q) -> (p,q)) vector1s
test1All "Pow(x,0)" (fun x -> BigRational.Pow(x,0)) (fun (p,q) -> (1I,1I)) vector1s
test1All "Pow(x,-1)" (fun x -> BigRational.Pow(x,-1)) (fun (p,q) -> (q,p)) (vector1s |> List.filter (fun (p,_) -> p <> 0I))
test1All "Pow(x,-2)" (fun x -> BigRational.Pow(x,-2)) (fun (p,q) -> (q*q,p*p)) (vector1s |> List.filter (fun (p,_) -> p <> 0I))
testR1One "Pow(0,-1)" (fun x -> throws (fun () -> BigRational.PowN(x,-1))) (fun (p,q) -> true) (0I, -1I)
testR1One "Pow(0,-2)" (fun x -> throws (fun () -> BigRational.PowN(x,-2))) (fun (p,q) -> true) (0I, -2I)
// MatteoT: moved to numbersVS2008\test.ml
//test1All "PowN(x,200)" (fun x -> BigRational.PowN(x,200)) (fun (p,q) -> (BigInteger.Pow(p,200I),BigInteger.Pow(q,200I))) vector1s
// MatteoT: moved to numbersVS2008\test.ml
//let powers = [0I .. 100I]
//powers |> List.iter (fun i -> test1All "PowN(x,i)" (fun x -> BigRational.PowN(x,int i)) (fun (p,q) -> (BigInteger.Pow(p,i),BigInteger.Pow(q,i))) vector1s)
[<TestFixture>]
type BigNumType() =
let g_positive1 = 1000000000000000000000000000000000018N
let g_positive2 = 1000000000000000000000000000000000000N
let g_negative1 = -1000000000000000000000000000000000018N
let g_negative2 = -1000000000000000000000000000000000000N
let g_negative3 = -1000000000000000000000000000000000036N
let g_zero = 0N
let g_normal = 88N
let g_bigintpositive = 1000000000000000000000000000000000018I
let g_bigintnegative = -1000000000000000000000000000000000018I
// Interfaces
[<Test>]
member this.IComparable() =
// Legit IC
let ic = g_positive1 :> IComparable
Assert.AreEqual(ic.CompareTo(g_positive1),0)
checkThrowsArgumentException( fun () -> ic.CompareTo(g_bigintpositive) |> ignore)
// Base class methods
[<Test>]
member this.ObjectToString() =
// Currently the CLR 4.0 and CLR 2.0 behavior of BigInt.ToString is different, causing this test to fail.
Assert.AreEqual(g_positive1.ToString(),
"1000000000000000000000000000000000018")
Assert.AreEqual(g_zero.ToString(),"0")
Assert.AreEqual(g_normal.ToString(),"88")
// Static methods
[<Test>]
member this.Abs() =
Assert.AreEqual(bignum.Abs(g_negative1), g_positive1)
Assert.AreEqual(bignum.Abs(g_negative2), g_positive2)
Assert.AreEqual(bignum.Abs(g_positive1), g_positive1)
Assert.AreEqual(bignum.Abs(g_normal), g_normal)
Assert.AreEqual(bignum.Abs(g_zero), g_zero)
()
[<Test>]
member this.FromBigInt() =
Assert.AreEqual(bignum.FromBigInt(g_bigintpositive),
g_positive1)
Assert.AreEqual(bignum.FromBigInt(g_bigintnegative),
g_negative1)
Assert.AreEqual(bignum.FromBigInt(0I),g_zero)
Assert.AreEqual(bignum.FromBigInt(88I),g_normal)
()
[<Test>]
member this.FromInt() =
Assert.AreEqual(bignum.FromInt(2147483647), 2147483647N)
Assert.AreEqual(bignum.FromInt(-2147483648), -2147483648N)
Assert.AreEqual(bignum.FromInt(0), 0N)
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>]
member this.Parse() =
Assert.AreEqual(bignum.Parse("100"), 100N)
Assert.AreEqual(bignum.Parse("-100"), -100N)
Assert.AreEqual(bignum.Parse("0"), g_zero)
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(2N,-2), 1N/4N)
Assert.AreEqual(bignum.Pow(2N/3N,-2), 9N/4N)
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)
Assert.AreEqual(bignum.PowN(-3N,3), -27N)
Assert.AreEqual(bignum.PowN(g_zero,2147483647), 0N)
Assert.AreEqual(bignum.PowN(g_normal,0), 1N)
()
[<Test>]
member this.Sign() =
Assert.AreEqual(g_positive1.Sign, 1)
Assert.AreEqual(g_negative1.Sign, -1)
Assert.AreEqual(g_zero.Sign, 0)
Assert.AreEqual(g_normal.Sign, 1)
()
[<Test>]
member this.ToBigInt() =
Assert.AreEqual(bignum.ToBigInt(g_positive1), g_bigintpositive)
Assert.AreEqual(bignum.ToBigInt(g_negative1), g_bigintnegative)
Assert.AreEqual(bignum.ToBigInt(g_zero), 0I)
Assert.AreEqual(bignum.ToBigInt(g_normal), 88I)
()
[<Test>]
member this.ToDouble() =
Assert.AreEqual(bignum.ToDouble(179769N*1000000000000000N), 1.79769E+20)
Assert.AreEqual(bignum.ToDouble(-179769N*1000000000000000N), -1.79769E+20)
Assert.AreEqual(bignum.ToDouble(0N),0.0)
Assert.AreEqual(bignum.ToDouble(88N),88.0)
Assert.AreEqual(double(179769N*1000000000000000N), 1.79769E+20)
Assert.AreEqual(double(-179769N*1000000000000000N), -1.79769E+20)
Assert.AreEqual(double(0N),0.0)
Assert.AreEqual(double(88N),88.0)
()
[<Test>]
member this.ToInt32() =
Assert.AreEqual(bignum.ToInt32(2147483647N), 2147483647)
Assert.AreEqual(bignum.ToInt32(-2147483648N), -2147483648)
Assert.AreEqual(bignum.ToInt32(0N), 0)
Assert.AreEqual(bignum.ToInt32(88N), 88)
Assert.AreEqual(int32(2147483647N), 2147483647)
Assert.AreEqual(int32(-2147483648N), -2147483648)
Assert.AreEqual(int32(0N), 0)
Assert.AreEqual(int32(88N), 88)
// operator methods
[<Test>]
member this.test_op_Addition() =
Assert.AreEqual(100N + 200N, 300N)
Assert.AreEqual((-100N) + (-200N), -300N)
Assert.AreEqual(g_positive1 + g_negative1, 0N)
Assert.AreEqual(g_zero + g_zero,0N)
Assert.AreEqual(g_normal + g_normal, 176N)
Assert.AreEqual(g_normal + g_normal, 176N)
()
[<Test>]
member this.test_op_Division() =
Assert.AreEqual(g_positive1 / g_positive1, 1N)
Assert.AreEqual(-100N / 2N, -50N)
Assert.AreEqual(g_zero / g_positive1, 0N)
()
[<Test>]
member this.test_op_Equality() =
Assert.IsTrue((g_positive1 = g_positive1))
Assert.IsTrue((g_negative1 = g_negative1))
Assert.IsTrue((g_zero = g_zero))
Assert.IsTrue((g_normal = g_normal))
()
[<Test>]
member this.test_op_GreaterThan() =
Assert.AreEqual((g_positive1 > g_positive2), true)
Assert.AreEqual((g_negative1 > g_negative2), false)
Assert.AreEqual((g_zero > g_zero), false)
Assert.AreEqual((g_normal > g_normal), false)
()
[<Test>]
member this.test_op_GreaterThanOrEqual() =
Assert.AreEqual((g_positive1 >= g_positive2), true)
Assert.AreEqual((g_positive2 >= g_positive1), false)
Assert.AreEqual((g_negative1 >= g_negative1), true)
Assert.AreEqual((0N >= g_zero), true)
()
[<Test>]
member this.test_op_LessThan() =
Assert.AreEqual((g_positive1 < g_positive2), false)
Assert.AreEqual((g_negative1 < g_negative3), false)
Assert.AreEqual((0N < g_zero), false)
()
[<Test>]
member this.test_op_LessThanOrEqual() =
Assert.AreEqual((g_positive1 <= g_positive2), false)
Assert.AreEqual((g_positive2 <= g_positive1), true)
Assert.AreEqual((g_negative1 <= g_negative1), true)
Assert.AreEqual((0N <= g_zero), true)
()
[<Test>]
member this.test_op_Multiply() =
Assert.AreEqual(3N * 5N, 15N)
Assert.AreEqual((-3N) * (-5N), 15N)
Assert.AreEqual((-3N) * 5N, -15N)
Assert.AreEqual(0N * 5N, 0N)
()
[<Test>]
member this.test_op_Range() =
let resultPos = [0N .. 2N]
let seqPos = [0N; 1N; 2N]
verifySeqsEqual resultPos seqPos
let resultNeg = [-2N .. 0N]
let seqNeg = [-2N; -1N; 0N]
verifySeqsEqual resultNeg seqNeg
let resultSmall = [0N ..5N]
let seqSmall = [0N; 1N; 2N; 3N; 4N; 5N]
verifySeqsEqual resultSmall seqSmall
()
[<Test>]
member this.test_op_RangeStep() =
let resultPos = [0N .. 3N .. 6N]
let seqPos = [0N; 3N; 6N]
verifySeqsEqual resultPos seqPos
let resultNeg = [-6N .. 3N .. 0N]
let seqNeg = [-6N; -3N; 0N]
verifySeqsEqual resultNeg seqNeg
let resultSmall = [0N .. 3N .. 9N]
let seqSmall = [0N; 3N; 6N; 9N]
verifySeqsEqual resultSmall seqSmall
()
[<Test>]
member this.test_op_Subtraction() =
Assert.AreEqual(g_positive1 - g_positive2,18N)
Assert.AreEqual(g_negative1 - g_negative3,18N)
Assert.AreEqual(0N-g_positive1, g_negative1)
()
[<Test>]
member this.test_op_UnaryNegation() =
Assert.AreEqual(-g_positive1, g_negative1)
Assert.AreEqual(-g_negative1, g_positive1)
Assert.AreEqual(-0N,0N)
()
[<Test>]
member this.test_op_UnaryPlus() =
Assert.AreEqual(+g_positive1,g_positive1)
Assert.AreEqual(+g_negative1,g_negative1)
Assert.AreEqual(+0N, 0N)
()
// instance methods
[<Test>]
member this.Denominator() =
Assert.AreEqual(g_positive1.Denominator, 1I)
Assert.AreEqual(g_negative1.Denominator, 1I)
Assert.AreEqual(0N.Denominator, 1I)
()
[<Test>]
member this.IsNegative() =
Assert.IsFalse(g_positive1.IsNegative)
Assert.IsTrue(g_negative1.IsNegative)
Assert.IsFalse( 0N.IsNegative)
Assert.IsFalse(-0N.IsNegative)
()
[<Test>]
member this.IsPositive() =
Assert.IsTrue(g_positive1.IsPositive)
Assert.IsFalse(g_negative1.IsPositive)
Assert.IsFalse( 0N.IsPositive)
Assert.IsFalse(-0N.IsPositive)
()
[<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)
Assert.AreEqual(g_negative1.Numerator, g_bigintnegative)
Assert.AreEqual(0N.Numerator, 0I)