namespace System.Unicode { /// Represents a rational number in a format compatible with the Unicode standard. public struct UnicodeRationalNumber : IEquatable { /// Parses a rational number from a string representation. /// /// Valid text representations should match the regex pattern /-?[0-9]+(?:\/[0-9]+)/. /// The numerator part should fit in a , and the denominator part should fit in a . /// /// The string to parse. /// The rational number parsed from the string. /// The parameter is . /// The parameter is empty. public static UnicodeRationalNumber Parse(string s) { if (s == null) throw new ArgumentNullException(nameof(s)); if (s.Length == 0) throw new ArgumentException(); int fractionBarIndex = s.IndexOf('/'); return new UnicodeRationalNumber(long.Parse(fractionBarIndex >= 0 ? s.Substring(0, fractionBarIndex) : s), fractionBarIndex >= 0 ? byte.Parse(s.Substring(fractionBarIndex + 1)) : (byte)1); } /// The numerator of the fraction. public readonly long Numerator; /// The denominator of the fraction. public readonly byte Denominator; /// Initializes a new instance of the structure that represents a signed integer.. /// The number which should be represented as a rational number. public UnicodeRationalNumber(long number) { this.Numerator = number; this.Denominator = 1; } /// Initializes a new instance of the structure that represents a signed integer.. /// The number which should be used as numerator in the rational number. /// The number which should be used as denominator in the rational number. public UnicodeRationalNumber(long numerator, byte denominator) { this.Numerator = numerator; this.Denominator = denominator; } /// Gets a value indicating whether the current value is the default value of the type. /// The default value is an invalid fraction of 0/0. public bool IsDefaultValue { get { return Numerator == 0 && Denominator == 0; } } /// Creates a string representation of the current rational number. /// The created representation is culture invariant, and will be parsable by the method. public override string ToString() { return !IsDefaultValue ? Denominator != 1 ? Numerator.ToString() + "/" + Denominator.ToString() : Numerator.ToString() : string.Empty; } /// Determines whether the specified rational number is equal to the current value. /// The other value to compare to the current one. /// if the two values are the same; otherwise. public bool Equals(UnicodeRationalNumber other) { // We don't consider 1/2 and 2/4 equal here, as, that wouldn't be the same character. return other.Numerator == Numerator && other.Denominator == Denominator; } /// Determines whether the specified object is equal to the current rational number. /// The object to compare to the current rational number. /// if the object represents the same rational number; otherwise. public override bool Equals(object obj) { return base.Equals(obj); } /// Returns the hash code for the current rational number. /// A 32-bit signed integer hash code. public override int GetHashCode() { return (int)(Numerator << 8) | (Denominator) ^ (byte)(Numerator >> 56); } } }