This is an old post, but no one has answered, and this information may be useful to others.
I don't know F# (so anyone who does, please edit my syntax), but the following methods in the Rational class should be of use. You will also need the BigInteger class from the Microsoft.SolverFoundation.Common name space.
(see https://learn.microsoft.com/en-us/previous-versions/visualstudio/ff526610)
First, as you point out, you can construct a Rational directly from other types using any of the many "implicit" constructors:
let Rational rat5 = Rational.op_Implicit(5.0:float)
let Rational rat2 = Rational.op_Implicit(2:int)
where I am guessing F# syntax.
As another quite illustrative example, monetary values (e.g. $10.43) can rarely be represented exactly with doubles. (The only "cents" values that wind up exact in a double are xx.00, xx.25, xx.50 and xx.75, all others wind up with numerical errors/differences.) So we often have to be careful when constructing a rational from a double that purports to represent a monetary value. This provides a good sample of another method of constructing rationals:
let BigInteger bi100 = BigInteger.op_Implicit(100:int)
let float mv = 1000000000000.43 //I am assuming this gets classified by F# as a double.
//Now, we assume mv is any double that represents a monetary value, and so should be an even 2 decimal places in base 10
//I have no idea how to Round in F#, nor how to cast to an integer - I have guessed - but should illustrate the idea if it is not valid F#
let BigInteger cents = BigInteger.op_Implicit( ( Round(mv * 100.0) ):int ) //get exact monetary value, in cents
let Rational ratMv = Rational.Get(cents:BigInteger, bi100:BigInteger)
and so we have constructed a Rational, from two BigInteger types, that exactly represents a monetary value mv stored as a double.
Here is the entire Rational interface, albeit in c#-syntax:
namespace Microsoft.SolverFoundation.Common
{
[CLSCompliant(true)]
public struct Rational : IComparable, IComparable<Rational>, IEquatable<Rational>, IComparable<BigInteger>, IEquatable<BigInteger>, IComparable<int>, IEquatable<int>, IComparable<uint>, IEquatable<uint>, IComparable<long>, IEquatable<long>, IComparable<ulong>, IEquatable<ulong>, IComparable<double>, IEquatable<double>
{
public static readonly Rational NegativeInfinity;
public static readonly Rational Zero;
public static readonly Rational One;
public static readonly Rational PositiveInfinity;
public static readonly Rational Indeterminate;
public static readonly Rational UnsignedInfinity;
public bool IsOne { get; }
public bool IsFinite { get; }
public bool IsIndeterminate { get; }
public bool IsInfinite { get; }
public bool IsSignedInfinity { get; }
public bool IsUnsignedInfinity { get; }
public bool HasSign { get; }
public bool IsNegativeInfinity { get; }
public bool IsZero { get; }
public int BitCount { get; }
public int Sign { get; }
public BigInteger Numerator { get; }
public bool IsPositiveInfinity { get; }
public BigInteger Denominator { get; }
public Rational AbsoluteValue { get; }
public static Rational AddMul(Rational ratAdd, Rational ratMul1, Rational ratMul2);
public static Rational Get(BigInteger bnNum, BigInteger bnDen);
public static void Negate(ref Rational num);
public static bool Power(Rational ratBase, Rational ratExp, out Rational ratRes);
public void AppendDecimalString(StringBuilder sb, int cchMax);
public int CompareTo(BigInteger bn);
[CLSCompliant(false)]
public int CompareTo(uint u);
public int CompareTo(Rational rat);
public int CompareTo(long nn);
[CLSCompliant(false)]
public int CompareTo(ulong uu);
public int CompareTo(double dbl);
public int CompareTo(int n);
public int CompareTo(object obj);
[CLSCompliant(false)]
public bool Equals(uint u);
public bool Equals(Rational rat);
public bool Equals(long nn);
[CLSCompliant(false)]
public bool Equals(ulong uu);
public bool Equals(int n);
public bool Equals(BigInteger bn);
public override bool Equals(object obj);
public bool Equals(double dbl);
public Rational GetCeiling();
public Rational GetCeilingResidual();
public Rational GetFloor();
public Rational GetFloorResidual();
public Rational GetFractionalPart();
public override int GetHashCode();
public Rational GetIntegerPart();
public double GetSignedDouble();
public Rational Invert();
public bool IsInteger(out BigInteger bn);
public bool IsInteger();
public double ToDouble();
public override string ToString();
public static Rational operator +(Rational rat1, Rational rat2);
public static Rational operator -(Rational rat);
public static Rational operator -(Rational rat1, Rational rat2);
public static Rational operator *(Rational rat1, Rational rat2);
public static Rational operator /(Rational rat1, Rational rat2);
[CLSCompliant(false)]
public static bool operator ==(uint n, Rational rat);
[CLSCompliant(false)]
public static bool operator ==(Rational rat, uint n);
public static bool operator ==(int n, Rational rat);
public static bool operator ==(long n, Rational rat);
public static bool operator ==(Rational rat, BigInteger bn);
public static bool operator ==(Rational rat, int n);
public static bool operator ==(Rational rat, long n);
public static bool operator ==(BigInteger bn, Rational rat);
public static bool operator ==(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator ==(Rational rat, ulong n);
public static bool operator ==(Rational rat1, Rational rat2);
[CLSCompliant(false)]
public static bool operator ==(ulong n, Rational rat);
public static bool operator ==(Rational rat, double dbl);
[CLSCompliant(false)]
public static bool operator !=(ulong n, Rational rat);
[CLSCompliant(false)]
public static bool operator !=(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator !=(uint n, Rational rat);
public static bool operator !=(BigInteger bn, Rational rat);
[CLSCompliant(false)]
public static bool operator !=(Rational rat, uint n);
public static bool operator !=(double dbl, Rational rat);
public static bool operator !=(int n, Rational rat);
public static bool operator !=(Rational rat, int n);
public static bool operator !=(long n, Rational rat);
public static bool operator !=(Rational rat, BigInteger bn);
public static bool operator !=(Rational rat1, Rational rat2);
public static bool operator !=(Rational rat, double dbl);
public static bool operator !=(Rational rat, long n);
public static bool operator <(double dbl, Rational rat);
public static bool operator <(Rational rat, double dbl);
[CLSCompliant(false)]
public static bool operator <(ulong n, Rational rat);
[CLSCompliant(false)]
public static bool operator <(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator <(uint n, Rational rat);
public static bool operator <(Rational rat1, Rational rat2);
public static bool operator <(Rational rat, BigInteger bn);
public static bool operator <(long n, Rational rat);
public static bool operator <(BigInteger bn, Rational rat);
public static bool operator <(Rational rat, int n);
public static bool operator <(int n, Rational rat);
[CLSCompliant(false)]
public static bool operator <(Rational rat, uint n);
public static bool operator <(Rational rat, long n);
public static bool operator >(long n, Rational rat);
public static bool operator >(Rational rat1, Rational rat2);
public static bool operator >(Rational rat, BigInteger bn);
public static bool operator >(BigInteger bn, Rational rat);
public static bool operator >(Rational rat, int n);
[CLSCompliant(false)]
public static bool operator >(Rational rat, uint n);
public static bool operator >(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator >(uint n, Rational rat);
public static bool operator >(int n, Rational rat);
public static bool operator >(Rational rat, long n);
public static bool operator >(Rational rat, double dbl);
[CLSCompliant(false)]
public static bool operator >(ulong n, Rational rat);
[CLSCompliant(false)]
public static bool operator >(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator <=(ulong n, Rational rat);
public static bool operator <=(Rational rat, int n);
public static bool operator <=(Rational rat, BigInteger bn);
public static bool operator <=(int n, Rational rat);
[CLSCompliant(false)]
public static bool operator <=(Rational rat, uint n);
public static bool operator <=(BigInteger bn, Rational rat);
[CLSCompliant(false)]
public static bool operator <=(Rational rat, ulong n);
public static bool operator <=(Rational rat1, Rational rat2);
public static bool operator <=(long n, Rational rat);
public static bool operator <=(Rational rat, double dbl);
public static bool operator <=(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator <=(uint n, Rational rat);
public static bool operator <=(Rational rat, long n);
public static bool operator >=(Rational rat, BigInteger bn);
public static bool operator >=(Rational rat1, Rational rat2);
[CLSCompliant(false)]
public static bool operator >=(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator >=(uint n, Rational rat);
public static bool operator >=(Rational rat, long n);
public static bool operator >=(int n, Rational rat);
public static bool operator >=(BigInteger bn, Rational rat);
public static bool operator >=(Rational rat, int n);
[CLSCompliant(false)]
public static bool operator >=(ulong n, Rational rat);
public static bool operator >=(long n, Rational rat);
public static bool operator >=(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator >=(Rational rat, uint n);
public static bool operator >=(Rational rat, double dbl);
public static implicit operator Rational(double dbl);
public static implicit operator Rational(BigInteger bn);
[CLSCompliant(false)]
public static implicit operator Rational(uint u);
public static implicit operator Rational(long nn);
[CLSCompliant(false)]
public static implicit operator Rational(ulong uu);
public static implicit operator Rational(int n);
public static explicit operator BigInteger(Rational rat);
public static explicit operator double(Rational rat);
[CLSCompliant(false)]
public static explicit operator ulong(Rational rat);
public static explicit operator long(Rational rat);
[CLSCompliant(false)]
public static explicit operator uint(Rational rat);
public static explicit operator int(Rational rat);
}
}
The other very useful bit of information that can be found at the above link is this table:
"The following table lists how special cases of rational numbers are represented.
Rational number |
Representation |
Non-zero finite rational values |
(numerator, denominator) with denominator > 0 |
Zero |
(0, 0) |
Negative infinity |
(-1, 0) |
Positive infinity |
(+1, 0) |
Unsigned infinity |
(+2, 0) |
Indeterminate (NaN) |
(+3, 0) |
Dividing a nonzero value by zero results in unsigned infinity because 0 is unsigned. Dividing a finite value by any infinite value results in 0."