这是一篇旧帖子,但没有人回答,这些信息可能对其他人有用。
我不知道 F#(所以任何知道的人,请编辑我的语法),但是 Rational 类中的以下方法应该是有用的。您还需要 Microsoft.SolverFoundation.Common 名称空间中的 BigInteger 类。(见https://docs.microsoft.com/en-us/previous-versions/visualstudio/ff526610)
首先,正如您所指出的,您可以使用许多“隐式”构造函数中的任何一个直接从其他类型构造一个 Rational:
let Rational rat5 = Rational.op_Implicit(5.0:float)
let Rational rat2 = Rational.op_Implicit(2:int)
我在哪里猜测 F# 语法。
作为另一个非常具有说明性的示例,货币价值(例如 10.43 美元)很少能用双精度数精确表示。(唯一以双精度结束的“美分”值是 xx.00、xx.25、xx.50 和 xx.75,所有其他值都以数字错误/差异结束。)所以我们经常必须小心从声称代表货币价值的双精度数构造一个理性。这为构建有理数的另一种方法提供了一个很好的示例:
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)
因此,我们从两个 BigInteger 类型构建了一个 Rational,它准确地表示存储为 double 的货币值 mv。
这是整个 Rational 界面,尽管是在 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);
}
}
可以在上面的链接中找到的另一个非常有用的信息是这个表:
“下表列出了有理数的特殊情况如何表示。
有理数 |
表示 |
非零有限有理值 |
(分子,分母)分母 > 0 |
零 |
(0, 0) |
负无穷大 |
(-1, 0) |
正无穷大 |
(+1, 0) |
无符号无穷大 |
(+2, 0) |
不确定 (NaN) |
(+3, 0) |
将非零值除以零会导致无符号无穷大,因为 0 是无符号的。将一个有限值除以任何无限值都会得到 0。”