//
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
//
namespace SixLabors.Primitives
{
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 SignedRational : IEquatable
{
///
/// Initializes a new instance of the struct.
///
/// The to create the rational from.
public SignedRational(int 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 SignedRational(int numerator, int 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 SignedRational(int numerator, int denominator, bool simplify)
{
LongRational rational = new LongRational(numerator, denominator, simplify);
this.Numerator = (int)rational.Numerator;
this.Denominator = (int)rational.Denominator;
}
///
/// Initializes a new instance of the struct.
///
/// The to create the instance from.
public SignedRational(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 SignedRational(double value, bool bestPrecision)
{
LongRational rational = new LongRational(value, bestPrecision);
this.Numerator = (int)rational.Numerator;
this.Denominator = (int)rational.Denominator;
}
///
/// Gets the numerator of a number.
///
public int Numerator { get; }
///
/// Gets the denominator of a number.
///
public int Denominator { get; }
///
/// Determines whether the specified instances are considered equal.
///
/// The first to compare.
/// The second to compare.
/// The
public static bool operator ==(SignedRational left, SignedRational right)
{
return SignedRational.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 !=(SignedRational left, SignedRational right)
{
return !SignedRational.Equals(left, right);
}
///
/// Converts the specified to an instance of this type.
///
/// The to convert to an instance of this type.
///
/// The .
///
public static SignedRational FromDouble(double value)
{
return new SignedRational(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 SignedRational FromDouble(double value, bool bestPrecision)
{
return new SignedRational(value, bestPrecision);
}
///
public override bool Equals(object obj)
{
if (obj is SignedRational)
{
return this.Equals((SignedRational)obj);
}
return false;
}
///
public bool Equals(SignedRational 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);
}
}
}