// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // namespace ImageProcessorCore { using System; using System.Globalization; /// /// Represents a number that can be expressed as a fraction. /// /// /// This is a very simplified implementation of a rational number designed for use with metadata only. /// public struct Rational : IEquatable { /// /// Initializes a new instance of the struct. /// /// The to create the rational from. public Rational(uint value) : this(value, 1) { } /// /// Initializes a new instance of the struct. /// /// The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken. /// The number below the line in a vulgar fraction; a divisor. public Rational(uint numerator, uint denominator) : this(numerator, denominator, true) { } /// /// Initializes a new instance of the struct. /// /// The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken. /// The number below the line in a vulgar fraction; a divisor. /// Specified if the rational should be simplified. public Rational(uint numerator, uint denominator, bool simplify) { LongRational rational = new LongRational(numerator, denominator, simplify); this.Numerator = (uint)rational.Numerator; this.Denominator = (uint)rational.Denominator; } /// /// Initializes a new instance of the struct. /// /// The to create the instance from. public Rational(double value) : this(value, false) { } /// /// Initializes a new instance of the struct. /// /// The to create the instance from. /// Whether to use the best possible precision when parsing the value. public Rational(double value, bool bestPrecision) { LongRational rational = new LongRational(Math.Abs(value), bestPrecision); this.Numerator = (uint)rational.Numerator; this.Denominator = (uint)rational.Denominator; } /// /// Gets the numerator of a number. /// public uint Numerator { get; } /// /// Gets the denominator of a number. /// public uint Denominator { get; } /// /// Determines whether the specified instances are considered equal. /// /// The first to compare. /// The second to compare. /// The public static bool operator ==(Rational left, Rational right) { return Rational.Equals(left, right); } /// /// Determines whether the specified instances are not considered equal. /// /// The first to compare. /// The second to compare. /// The public static bool operator !=(Rational left, Rational right) { return !Rational.Equals(left, right); } /// /// Converts the specified to an instance of this type. /// /// The to convert to an instance of this type. /// /// The . /// public static Rational FromDouble(double value) { return new Rational(value, false); } /// /// Converts the specified to an instance of this type. /// /// The to convert to an instance of this type. /// Whether to use the best possible precision when parsing the value. /// /// The . /// public static Rational FromDouble(double value, bool bestPrecision) { return new Rational(value, bestPrecision); } /// public override bool Equals(object obj) { if (obj is Rational) { return this.Equals((Rational)obj); } return false; } /// public bool Equals(Rational other) { LongRational left = new LongRational(this.Numerator, this.Denominator); LongRational right = new LongRational(other.Numerator, other.Denominator); return left.Equals(right); } /// public override int GetHashCode() { LongRational self = new LongRational(this.Numerator, this.Denominator); return self.GetHashCode(); } /// /// Converts a rational number to the nearest . /// /// /// The . /// public double ToDouble() { return this.Numerator / (double)this.Denominator; } /// public override string ToString() { return this.ToString(CultureInfo.InvariantCulture); } /// /// Converts the numeric value of this instance to its equivalent string representation using /// the specified culture-specific format information. /// /// /// An object that supplies culture-specific formatting information. /// /// The public string ToString(IFormatProvider provider) { LongRational rational = new LongRational(this.Numerator, this.Denominator); return rational.ToString(provider); } } }