revert move fraction internal (#366)
This commit is contained in:
@@ -1,128 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions.Extensions {
|
|
||||||
internal static class MathExt {
|
|
||||||
/// <summary>
|
|
||||||
/// Checks for an even number.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="number"></param>
|
|
||||||
/// <returns><c>true</c> if the number is even.</returns>
|
|
||||||
public static bool IsEven(this long number) {
|
|
||||||
return (number & 1) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks for an odd number.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="number"></param>
|
|
||||||
/// <returns><c>true</c> if the number is odd.</returns>
|
|
||||||
public static bool IsOdd(this long number) {
|
|
||||||
return (number & 1) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the greatest common divisor (GCD) of <paramref name="a"/> and <paramref name="b"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="a">First number.</param>
|
|
||||||
/// <param name="b">Second number.</param>
|
|
||||||
/// <returns>The largest positive integer that divides <paramref name="a"/> and <paramref name="b"/> without a remainder.</returns>
|
|
||||||
public static long GreatestCommonDivisor(long a, long b) {
|
|
||||||
a = Math.Abs(a);
|
|
||||||
b = Math.Abs(b);
|
|
||||||
|
|
||||||
if (a == 0) {
|
|
||||||
// ggT(0, b) = b
|
|
||||||
// Denn alles teilt durch 0.
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b == 0) {
|
|
||||||
// ggT(a, 0) = a
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a == 1 || b == 1) {
|
|
||||||
// trivial
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a == b
|
|
||||||
? a // Beide Zahlen sind identisch, wir haben bereits den ggT gefunden.
|
|
||||||
: BinaryGreatestCommonDivisorAlgorithm(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long BinaryGreatestCommonDivisorAlgorithm(long a, long b) {
|
|
||||||
|
|
||||||
// Solange 'a' und 'b' beide gerade Zahlen sind, teile die Zahlen durch 2
|
|
||||||
// und merke wie oft dies möglich war in 'k'.
|
|
||||||
int k;
|
|
||||||
for (k = 0; (a | b).IsEven(); ++k) {
|
|
||||||
a >>= 1; // a = (a / 2);
|
|
||||||
b >>= 1; // b = (b / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Teile 'a' solange durch 2 bis die Zahl ungerade ist.
|
|
||||||
while (a.IsEven()) {
|
|
||||||
a >>= 1; // a = (a / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ab hier ist 'a' definitiv ungerade. Für 'b' muss dies allerdings noch nicht gelten!
|
|
||||||
do {
|
|
||||||
// Teile 'b' solange durch 2 bis die Zahl ungerade ist.
|
|
||||||
while (b.IsEven()) {
|
|
||||||
b >>= 1; // b = (b / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'a' und 'b' sind hier beide ungerade. Falls 'a' >= 'b'
|
|
||||||
// muss der Inhalt beider Variablen geswappt werden,
|
|
||||||
// damit die notwendige Subtraktion durchgeführt werden
|
|
||||||
// kann.
|
|
||||||
if (a > b) {
|
|
||||||
var temp = b;
|
|
||||||
b = a;
|
|
||||||
a = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
b = b - a;
|
|
||||||
|
|
||||||
} while (b != 0);
|
|
||||||
|
|
||||||
return a << k; // a * 2^k
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the least common multiple (LCM) of <paramref name="a"/> and <paramref name="b"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="a">The first number.</param>
|
|
||||||
/// <param name="b">The second number.</param>
|
|
||||||
/// <returns>The smallest positive integer that is divisible by both <paramref name="a"/> and <paramref name="b"/> or 0 if either <paramref name="a"/> or <paramref name="b"/> is 0</returns>
|
|
||||||
/// <exception cref="ArgumentException">If <paramref name="a"/> and <paramref name="b"/> are 0</exception>
|
|
||||||
public static long LeastCommonMultiple(long a, long b) {
|
|
||||||
if (a == 0 && b == 0) {
|
|
||||||
throw new ArgumentException("The least common multiple is not defined if both numbers are zero.");
|
|
||||||
}
|
|
||||||
|
|
||||||
a = Math.Abs(a);
|
|
||||||
b = Math.Abs(b);
|
|
||||||
|
|
||||||
if (a == b) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Es gilt LCM(a,b) = (|a*b|) / GCD(a,b)
|
|
||||||
|
|
||||||
var gcd = GreatestCommonDivisor(a, b);
|
|
||||||
return a / gcd * b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns <c>true</c> if there are remaining digits after the decimal point.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="remainingDigits">A <see cref="double"/> value with possible remaining digits</param>
|
|
||||||
/// <returns><c>true</c> if <paramref name="remainingDigits"/> has digits after the decimal point</returns>
|
|
||||||
|
|
||||||
public static bool RemainingDigitsAfterTheDecimalPoint(double remainingDigits) {
|
|
||||||
return Math.Abs(remainingDigits - Math.Floor(remainingDigits)) > double.Epsilon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions.Formatter {
|
|
||||||
/// <summary>
|
|
||||||
/// Default <see cref="Fraction.ToString()"/> formatter.
|
|
||||||
/// </summary>
|
|
||||||
internal class DefaultFractionFormatProvider : IFormatProvider {
|
|
||||||
/// <summary>
|
|
||||||
/// Singleton instance
|
|
||||||
/// </summary>
|
|
||||||
public static readonly IFormatProvider Instance = new DefaultFractionFormatProvider();
|
|
||||||
|
|
||||||
object IFormatProvider.GetFormat(Type formatType) {
|
|
||||||
return formatType == typeof (Fraction)
|
|
||||||
? DefaultFractionFormatter.Instance
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Numerics;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions.Formatter {
|
|
||||||
internal class DefaultFractionFormatter : ICustomFormatter {
|
|
||||||
public static readonly ICustomFormatter Instance = new DefaultFractionFormatter();
|
|
||||||
|
|
||||||
public string Format(string format, object arg, IFormatProvider formatProvider) {
|
|
||||||
if (arg == null) {
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(arg is Fraction)) {
|
|
||||||
throw new FormatException(string.Format("The type {0} is not supported.", arg.GetType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var fraction = (Fraction)arg;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(format) || format == "G") {
|
|
||||||
return FormatGeneral(fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
var sb = new StringBuilder(32);
|
|
||||||
foreach (var character in format) {
|
|
||||||
switch (character) {
|
|
||||||
case 'G':
|
|
||||||
sb.Append(FormatGeneral(fraction));
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
sb.Append(fraction.Numerator.ToString(CultureInfo.InvariantCulture));
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
sb.Append(fraction.Denominator.ToString(CultureInfo.InvariantCulture));
|
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
sb.Append(FormatInteger(fraction));
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
sb.Append(FormatRemainder(fraction));
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
sb.Append(FormatMixed(fraction));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sb.Append(character);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatMixed(Fraction fraction) {
|
|
||||||
if (BigInteger.Abs(fraction.Numerator) < BigInteger.Abs(fraction.Denominator)) {
|
|
||||||
return FormatGeneral(fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
var integer = fraction.Numerator / fraction.Denominator;
|
|
||||||
var remainder = Fraction.Abs(fraction - integer);
|
|
||||||
|
|
||||||
return remainder.IsZero
|
|
||||||
? integer.ToString(CultureInfo.InvariantCulture)
|
|
||||||
: string.Concat(
|
|
||||||
integer.ToString(CultureInfo.InvariantCulture),
|
|
||||||
" ",
|
|
||||||
FormatGeneral(remainder));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatInteger(Fraction fraction) {
|
|
||||||
return (fraction.Numerator / fraction.Denominator)
|
|
||||||
.ToString(CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatRemainder(Fraction fraction) {
|
|
||||||
if (BigInteger.Abs(fraction.Numerator) < BigInteger.Abs(fraction.Denominator)) {
|
|
||||||
return FormatGeneral(fraction);
|
|
||||||
}
|
|
||||||
var integer = fraction.Numerator / fraction.Denominator;
|
|
||||||
var remainder = fraction - integer;
|
|
||||||
return FormatGeneral(remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatGeneral(Fraction fraction) {
|
|
||||||
if (fraction.Denominator == BigInteger.One) {
|
|
||||||
return fraction.Numerator.ToString(CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
}
|
|
||||||
return string.Concat(
|
|
||||||
fraction.Numerator.ToString(CultureInfo.InvariantCulture),
|
|
||||||
"/",
|
|
||||||
fraction.Denominator.ToString(CultureInfo.InvariantCulture));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the calculated value with the supplied <paramref name="other"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">Fraction that shall be compared with.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Less than 0 if <paramref name="other"/> is greater.
|
|
||||||
/// Zero (0) if both calculated values are equal.
|
|
||||||
/// Greater then zero (0) if <paramref name="other"/> less.</returns>
|
|
||||||
/// <exception cref="ArgumentException">If <paramref name="other"/> is not of type <see cref="Fraction"/>.</exception>
|
|
||||||
public int CompareTo(object other) {
|
|
||||||
if (other == null) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.GetType() != typeof(Fraction)) {
|
|
||||||
throw new ArgumentException(
|
|
||||||
string.Format("The comparing instance must be of type {0}. The supplied argument is of type {1}", GetType(), other.GetType()), nameof(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
return CompareTo((Fraction)other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the calculated value with the supplied <paramref name="other"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">Fraction that shall be compared with.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Less than 0 if <paramref name="other"/> is greater.
|
|
||||||
/// Zero (0) if both calculated values are equal.
|
|
||||||
/// Greater then zero (0) if <paramref name="other"/> less.</returns>
|
|
||||||
|
|
||||||
public int CompareTo(Fraction other) {
|
|
||||||
if (_denominator == other._denominator) {
|
|
||||||
return _numerator.CompareTo(other._numerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsZero != other.IsZero) {
|
|
||||||
if (IsZero) {
|
|
||||||
return other.IsPositive ? -1 : 1;
|
|
||||||
}
|
|
||||||
return IsPositive ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var gcd = BigInteger.GreatestCommonDivisor(_denominator, other._denominator);
|
|
||||||
|
|
||||||
var thisMultiplier = BigInteger.Divide(_denominator, gcd);
|
|
||||||
var otherMultiplier = BigInteger.Divide(other._denominator, gcd);
|
|
||||||
|
|
||||||
var a = BigInteger.Multiply(_numerator, otherMultiplier);
|
|
||||||
var b = BigInteger.Multiply(other._numerator, thisMultiplier);
|
|
||||||
|
|
||||||
return a.CompareTo(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Create a fraction with <paramref name="numerator"/>, <paramref name="denominator"/> and the fraction' <paramref name="state"/>.
|
|
||||||
/// Warning: if you use unreduced values combined with a state of <see cref="FractionState.IsNormalized"/>
|
|
||||||
/// you will get wrong results when working with the fraction value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator"></param>
|
|
||||||
/// <param name="denominator"></param>
|
|
||||||
/// <param name="state"></param>
|
|
||||||
private Fraction(BigInteger numerator, BigInteger denominator, FractionState state) {
|
|
||||||
_numerator = numerator;
|
|
||||||
_denominator = denominator;
|
|
||||||
_state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized (reduced/simplified) fraction using <paramref name="numerator"/> and <paramref name="denominator"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">Numerator</param>
|
|
||||||
/// <param name="denominator">Denominator</param>
|
|
||||||
public Fraction(BigInteger numerator, BigInteger denominator)
|
|
||||||
: this(numerator, denominator, true) { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized (reduced/simplified) or unnormalized fraction using <paramref name="numerator"/> and <paramref name="denominator"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">Numerator</param>
|
|
||||||
/// <param name="denominator">Denominator</param>
|
|
||||||
/// <param name="normalize">If <c>true</c> the fraction will be created as reduced/simplified fraction.
|
|
||||||
/// This is recommended, especially if your applications requires that the results of the equality methods <see cref="object.Equals(object)"/>
|
|
||||||
/// and <see cref="IComparable.CompareTo"/> are always the same. (1/2 != 2/4)</param>
|
|
||||||
public Fraction(BigInteger numerator, BigInteger denominator, bool normalize) {
|
|
||||||
if (normalize) {
|
|
||||||
this = GetReducedFraction(numerator, denominator);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_state = numerator.IsZero && denominator.IsZero
|
|
||||||
? FractionState.IsNormalized
|
|
||||||
: FractionState.Unknown;
|
|
||||||
|
|
||||||
_numerator = numerator;
|
|
||||||
_denominator = denominator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized fraction using a signed 32bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">integer value that will be used for the numerator. The denominator will be 1.</param>
|
|
||||||
public Fraction(int numerator) {
|
|
||||||
_numerator = new BigInteger(numerator);
|
|
||||||
_denominator = numerator != 0 ? BigInteger.One : BigInteger.Zero;
|
|
||||||
_state = FractionState.IsNormalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized fraction using a signed 64bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">integer value that will be used for the numerator. The denominator will be 1.</param>
|
|
||||||
public Fraction(long numerator) {
|
|
||||||
_numerator = new BigInteger(numerator);
|
|
||||||
_denominator = numerator != 0 ? BigInteger.One : BigInteger.Zero;
|
|
||||||
_state = FractionState.IsNormalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized fraction using a unsigned 32bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">integer value that will be used for the numerator. The denominator will be 1.</param>
|
|
||||||
public Fraction(uint numerator) {
|
|
||||||
_numerator = new BigInteger(numerator);
|
|
||||||
_denominator = numerator != 0 ? BigInteger.One : BigInteger.Zero;
|
|
||||||
_state = FractionState.IsNormalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized fraction using a unsigned 64bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">integer value that will be used for the numerator. The denominator will be 1.</param>
|
|
||||||
public Fraction(ulong numerator) {
|
|
||||||
_numerator = new BigInteger(numerator);
|
|
||||||
_denominator = numerator != 0 ? BigInteger.One : BigInteger.Zero;
|
|
||||||
_state = FractionState.IsNormalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized fraction using a big integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">big integer value that will be used for the numerator. The denominator will be 1.</param>
|
|
||||||
public Fraction(BigInteger numerator) {
|
|
||||||
_numerator = numerator;
|
|
||||||
_denominator = numerator.IsZero ? BigInteger.Zero : BigInteger.One;
|
|
||||||
_state = FractionState.IsNormalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized fraction using a 64bit floating point value (double).
|
|
||||||
/// The value will not be rounded therefore you will probably get huge numbers as numerator und denominator.
|
|
||||||
/// <see cref="double"/> values are not able to store simple rational numbers like 0.2 or 0.3 - so please
|
|
||||||
/// don't be worried if the fraction looks weird. For more information visit
|
|
||||||
/// http://en.wikipedia.org/wiki/Floating_point
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">Floating point value.</param>
|
|
||||||
public Fraction(double value) {
|
|
||||||
this = FromDouble(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a normalized fraction using a 128bit decimal value (decimal).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">Floating point value.</param>
|
|
||||||
public Fraction(decimal value) {
|
|
||||||
this = FromDecimal(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,314 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Numerics;
|
|
||||||
using k8s.Internal.Fractions.Extensions;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction {
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a string to a fraction. Example: "3/4" or "4.5" (the decimal separator character is depending on the system culture).
|
|
||||||
/// If the number contains a decimal separator it will be parsed as <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fractionString">A fraction or a (decimal) number. The numerator and denominator must be separated with a '/' (slash) character.</param>
|
|
||||||
/// <returns>A normalized <see cref="Fraction"/></returns>
|
|
||||||
public static Fraction FromString(string fractionString) {
|
|
||||||
return FromString(fractionString, NumberStyles.Number, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a string to a fraction. Example: "3/4" or "4.5" (the decimal separator character depends on <paramref name="formatProvider"/>).
|
|
||||||
/// If the number contains a decimal separator it will be parsed as <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fractionString">A fraction or a (decimal) number. The numerator and denominator must be separated with a '/' (slash) character.</param>
|
|
||||||
/// <param name="formatProvider">Provides culture specific information that will be used to parse the <paramref name="fractionString"/>.</param>
|
|
||||||
/// <returns>A normalized <see cref="Fraction"/></returns>
|
|
||||||
public static Fraction FromString(string fractionString, IFormatProvider formatProvider) {
|
|
||||||
return FromString(fractionString, NumberStyles.Number, formatProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a string to a fraction. Example: "3/4" or "4.5" (the decimal separator character depends on <paramref name="formatProvider"/>).
|
|
||||||
/// If the number contains a decimal separator it will be parsed as <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fractionString">A fraction or a (decimal) number. The numerator and denominator must be separated with a '/' (slash) character.</param>
|
|
||||||
/// <param name="numberStyles">A bitwise combination of number styles that are allowed in <paramref name="fractionString"/>.</param>
|
|
||||||
/// <param name="formatProvider">Provides culture specific information that will be used to parse the <paramref name="fractionString"/>.</param>
|
|
||||||
/// <returns>A normalized <see cref="Fraction"/></returns>
|
|
||||||
public static Fraction FromString(string fractionString, NumberStyles numberStyles, IFormatProvider formatProvider) {
|
|
||||||
if (fractionString == null) {
|
|
||||||
throw new ArgumentNullException(nameof(fractionString));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TryParse(fractionString, numberStyles, formatProvider, true, out Fraction fraction)) {
|
|
||||||
throw new FormatException(string.Format("The string '{0}' cannot be converted to fraction.", fractionString));
|
|
||||||
}
|
|
||||||
|
|
||||||
return fraction;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to convert a string to a fraction. Example: "3/4" or "4.5" (the decimal separator character depends on the system's culture).
|
|
||||||
/// If the number contains a decimal separator it will be parsed as <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fractionString">A fraction or a (decimal) number. The numerator and denominator must be separated with a '/' (slash) character.</param>
|
|
||||||
/// <param name="fraction">A normalized <see cref="Fraction"/> if the method returns with <c>true</c>. Otherwise the value is invalid.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <para><c>true</c> if <paramref name="fractionString"/> was well formed. The parsing result will be written to <paramref name="fraction"/>. </para>
|
|
||||||
/// <para><c>false</c> if <paramref name="fractionString"/> was invalid.</para></returns>
|
|
||||||
public static bool TryParse(string fractionString, out Fraction fraction) {
|
|
||||||
return TryParse(fractionString, NumberStyles.Number, null, true, out fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to convert a string to a fraction. Example: "3/4" or "4.5" (the decimal separator character depends on <paramref name="formatProvider"/>).
|
|
||||||
/// If the number contains a decimal separator it will be parsed as <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fractionString">A fraction or a (decimal) number. The numerator and denominator must be separated with a '/' (slash) character.</param>
|
|
||||||
/// <param name="numberStyles">A bitwise combination of number styles that are allowed in <paramref name="fractionString"/>.</param>
|
|
||||||
/// <param name="formatProvider">Provides culture specific information that will be used to parse the <paramref name="fractionString"/>.</param>
|
|
||||||
/// <param name="fraction">A normalized <see cref="Fraction"/> if the method returns with <c>true</c>. Otherwise the value is invalid.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <para><c>true</c> if <paramref name="fractionString"/> was well formed. The parsing result will be written to <paramref name="fraction"/>. </para>
|
|
||||||
/// <para><c>false</c> if <paramref name="fractionString"/> was invalid.</para>
|
|
||||||
/// </returns>
|
|
||||||
public static bool TryParse(string fractionString, NumberStyles numberStyles, IFormatProvider formatProvider, out Fraction fraction) {
|
|
||||||
return TryParse(fractionString, numberStyles, formatProvider, true, out fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to convert a string to a fraction. Example: "3/4" or "4.5" (the decimal separator character depends on <paramref name="formatProvider"/>).
|
|
||||||
/// If the number contains a decimal separator it will be parsed as <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fractionString">A fraction or a (decimal) number. The numerator and denominator must be separated with a '/' (slash) character.</param>
|
|
||||||
/// <param name="numberStyles">A bitwise combination of number styles that are allowed in <paramref name="fractionString"/>.</param>
|
|
||||||
/// <param name="formatProvider">Provides culture specific information that will be used to parse the <paramref name="fractionString"/>.</param>
|
|
||||||
/// <param name="normalize">If <c>true</c> the parsed fraction will be reduced.</param>
|
|
||||||
/// <param name="fraction">A <see cref="Fraction"/> if the method returns with <c>true</c>. Otherwise the value is invalid.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <para><c>true</c> if <paramref name="fractionString"/> was well formed. The parsing result will be written to <paramref name="fraction"/>. </para>
|
|
||||||
/// <para><c>false</c> if <paramref name="fractionString"/> was invalid.</para>
|
|
||||||
/// </returns>
|
|
||||||
public static bool TryParse(string fractionString, NumberStyles numberStyles, IFormatProvider formatProvider, bool normalize, out Fraction fraction) {
|
|
||||||
if (fractionString == null) {
|
|
||||||
return CannotParse(out fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
var components = fractionString.Split('/');
|
|
||||||
if (components.Length == 1) {
|
|
||||||
return TryParseSingleNumber(components[0], numberStyles, formatProvider, out fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.Length >= 2) {
|
|
||||||
var numeratorString = components[0];
|
|
||||||
var denominatorString = components[1];
|
|
||||||
|
|
||||||
var withoutDecimalpoint = numberStyles & ~NumberStyles.AllowDecimalPoint;
|
|
||||||
if (!BigInteger.TryParse(
|
|
||||||
value: numeratorString,
|
|
||||||
style: withoutDecimalpoint,
|
|
||||||
provider: formatProvider,
|
|
||||||
result: out BigInteger numerator)
|
|
||||||
|| !BigInteger.TryParse(
|
|
||||||
value: denominatorString,
|
|
||||||
style: withoutDecimalpoint,
|
|
||||||
provider: formatProvider,
|
|
||||||
result: out BigInteger denominator)) {
|
|
||||||
return CannotParse(out fraction);
|
|
||||||
}
|
|
||||||
fraction = new Fraction(numerator, denominator, normalize);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Technically it should not be possible to reach this line of code..
|
|
||||||
return CannotParse(out fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to convert a single number to a fraction. Example 34 or 4.5 (depending on the supplied culture used in <paramref name="formatProvider"/>)
|
|
||||||
/// If the number contains a decimal separator it will be parsed as <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="number">A (decimal) number</param>
|
|
||||||
/// <param name="numberStyles">A bitwise combination of number styles that are allowed in <paramref name="number"/>.</param>
|
|
||||||
/// <param name="formatProvider">Provides culture specific information that will be used to parse the <paramref name="number"/>.</param>
|
|
||||||
/// <param name="fraction">A <see cref="Fraction"/> if the method returns with <c>true</c>. Otherwise the value is invalid.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <para><c>true</c> if <paramref name="number"/> was well formed. The parsing result will be written to <paramref name="fraction"/>. </para>
|
|
||||||
/// <para><c>false</c> if <paramref name="number"/> was invalid.</para>
|
|
||||||
/// </returns>
|
|
||||||
private static bool TryParseSingleNumber(string number, NumberStyles numberStyles, IFormatProvider formatProvider, out Fraction fraction) {
|
|
||||||
var numberFormatInfo = NumberFormatInfo.GetInstance(formatProvider);
|
|
||||||
|
|
||||||
if (number.Contains(numberFormatInfo.NumberDecimalSeparator)) {
|
|
||||||
if (!decimal.TryParse(number, numberStyles, formatProvider, out decimal decimalNumber)) {
|
|
||||||
return CannotParse(out fraction);
|
|
||||||
}
|
|
||||||
fraction = FromDecimal(decimalNumber);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var withoutDecimalpoint = numberStyles & ~NumberStyles.AllowDecimalPoint;
|
|
||||||
if (!BigInteger.TryParse(number, withoutDecimalpoint, formatProvider, out BigInteger numerator)) {
|
|
||||||
return CannotParse(out fraction);
|
|
||||||
}
|
|
||||||
fraction = new Fraction(numerator);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns false. <paramref name="fraction"/> contains an invalid value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fraction">Returns <c>default()</c> of <see cref="Fraction"/></param>
|
|
||||||
/// <returns><c>false</c></returns>
|
|
||||||
private static bool CannotParse(out Fraction fraction) {
|
|
||||||
fraction = default(Fraction);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a floating point value to a fraction. The value will not be rounded therefore you will probably
|
|
||||||
/// get huge numbers as numerator und denominator. <see cref="double"/> values are not able to store simple rational
|
|
||||||
/// numbers like 0.2 or 0.3 - so please don't be worried if the fraction looks weird. For more information visit
|
|
||||||
/// http://en.wikipedia.org/wiki/Floating_point
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">A floating point value.</param>
|
|
||||||
/// <returns>A fraction</returns>
|
|
||||||
/// <exception cref="InvalidNumberException">If <paramref name="value"/> is NaN (not a number) or infinite.</exception>
|
|
||||||
public static Fraction FromDouble(double value) {
|
|
||||||
if (double.IsNaN(value) || double.IsInfinity(value)) {
|
|
||||||
throw new InvalidNumberException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// No rounding here! It will convert the actual number that is stored as double!
|
|
||||||
// See http://www.mpdvc.de/artikel/FloatingPoint.htm
|
|
||||||
|
|
||||||
const ulong SIGN_BIT = 0x8000000000000000;
|
|
||||||
const ulong EXPONENT_BITS = 0x7FF0000000000000;
|
|
||||||
const ulong MANTISSA = 0x000FFFFFFFFFFFFF;
|
|
||||||
const ulong MANTISSA_DIVISOR = 0x0010000000000000;
|
|
||||||
const ulong K = 1023;
|
|
||||||
var one = BigInteger.One;
|
|
||||||
|
|
||||||
// value = (-1 * sign) * (1 + 2^(-1) + 2^(-2) .. + 2^(-52)) * 2^(exponent-K)
|
|
||||||
var valueBits = unchecked((ulong) BitConverter.DoubleToInt64Bits(value));
|
|
||||||
|
|
||||||
if (valueBits == 0) {
|
|
||||||
// See IEEE 754
|
|
||||||
return Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
var isNegative = (valueBits & SIGN_BIT) == SIGN_BIT;
|
|
||||||
var mantissaBits = valueBits & MANTISSA;
|
|
||||||
|
|
||||||
// (exponent-K)
|
|
||||||
var exponent = (int) (((valueBits & EXPONENT_BITS) >> 52) - K);
|
|
||||||
|
|
||||||
// (1 + 2^(-1) + 2^(-2) .. + 2^(-52))
|
|
||||||
var mantissa = new Fraction(mantissaBits + MANTISSA_DIVISOR, MANTISSA_DIVISOR);
|
|
||||||
|
|
||||||
// 2^exponent
|
|
||||||
var factor = exponent < 0
|
|
||||||
? new Fraction(one, one << Math.Abs(exponent))
|
|
||||||
: new Fraction(one << exponent);
|
|
||||||
|
|
||||||
var result = mantissa * factor;
|
|
||||||
|
|
||||||
return isNegative
|
|
||||||
? result.Invert()
|
|
||||||
: result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a floating point value to a fraction. The value will be rounded if possible.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">A floating point value.</param>
|
|
||||||
/// <returns>A fraction</returns>
|
|
||||||
/// <exception cref="InvalidNumberException">If <paramref name="value"/> is NaN (not a number) or infinite.</exception>
|
|
||||||
public static Fraction FromDoubleRounded(double value) {
|
|
||||||
if (double.IsNaN(value) || double.IsInfinity(value)) {
|
|
||||||
throw new InvalidNumberException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Null?
|
|
||||||
if (Math.Abs(value - 0.0) < double.Epsilon) {
|
|
||||||
return Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inspired from Syed Mehroz Alam <smehrozalam@yahoo.com> http://www.geocities.ws/smehrozalam/source/fractioncs.txt
|
|
||||||
// .. who got it from http://ebookbrowse.com/confrac-pdf-d13212190
|
|
||||||
// or ftp://89.25.159.69/knm/ksiazki/reszta/homepage.smc.edu.kennedy_john/CONFRAC.pdf
|
|
||||||
var sign = Math.Sign(value);
|
|
||||||
var absoluteValue = Math.Abs(value);
|
|
||||||
|
|
||||||
var numerator = new BigInteger(absoluteValue);
|
|
||||||
var denominator = 1.0;
|
|
||||||
var remainingDigits = absoluteValue;
|
|
||||||
var previousDenominator = 0.0;
|
|
||||||
var breakCounter = 0;
|
|
||||||
|
|
||||||
while (MathExt.RemainingDigitsAfterTheDecimalPoint(remainingDigits)
|
|
||||||
&& Math.Abs(absoluteValue - (double) numerator / denominator) > double.Epsilon) {
|
|
||||||
|
|
||||||
remainingDigits = 1.0 / (remainingDigits - Math.Floor(remainingDigits));
|
|
||||||
|
|
||||||
var tmp = denominator;
|
|
||||||
|
|
||||||
denominator = Math.Floor(remainingDigits) * denominator + previousDenominator;
|
|
||||||
numerator = new BigInteger(absoluteValue * denominator + 0.5);
|
|
||||||
|
|
||||||
previousDenominator = tmp;
|
|
||||||
|
|
||||||
// See http://www.ozgrid.com/forum/archive/index.php/t-22530.html
|
|
||||||
if (++breakCounter > 594) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Fraction(
|
|
||||||
sign < 0 ? BigInteger.Negate(numerator) : numerator,
|
|
||||||
new BigInteger(denominator),
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a decimal value in a fraction. The value will not be rounded.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">A decimal value.</param>
|
|
||||||
/// <returns>A fraction.</returns>
|
|
||||||
public static Fraction FromDecimal(decimal value) {
|
|
||||||
if (value == decimal.Zero) {
|
|
||||||
return _zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == decimal.One) {
|
|
||||||
return _one;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == decimal.MinusOne) {
|
|
||||||
return _minus_one;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bits = decimal.GetBits(value);
|
|
||||||
var low = BitConverter.GetBytes(bits[0]);
|
|
||||||
var middle = BitConverter.GetBytes(bits[1]);
|
|
||||||
var high = BitConverter.GetBytes(bits[2]);
|
|
||||||
var scale = BitConverter.GetBytes(bits[3]);
|
|
||||||
|
|
||||||
|
|
||||||
var exp = scale[2];
|
|
||||||
bool positiveSign = (scale[3] & 0x80) == 0;
|
|
||||||
|
|
||||||
// value = 0x00,high,middle,low / 10^exp
|
|
||||||
var numerator = new BigInteger(new byte[] {
|
|
||||||
low[0], low[1], low[2], low[3],
|
|
||||||
middle[0], middle[1], middle[2], middle[3],
|
|
||||||
high[0], high[1], high[2], high[3],
|
|
||||||
0x00
|
|
||||||
});
|
|
||||||
var denominator = BigInteger.Pow(10, exp);
|
|
||||||
|
|
||||||
return positiveSign
|
|
||||||
? new Fraction(numerator, denominator, true)
|
|
||||||
: new Fraction(BigInteger.Negate(numerator), denominator, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction {
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as signed 32bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>32bit signed integer</returns>
|
|
||||||
public int ToInt32() {
|
|
||||||
if (IsZero) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) (Numerator / Denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as signed 64bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>64bit signed integer</returns>
|
|
||||||
public long ToInt64() {
|
|
||||||
if (IsZero) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (long) (Numerator / Denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as unsigned 32bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>32bit unsigned integer</returns>
|
|
||||||
public uint ToUInt32() {
|
|
||||||
if (IsZero) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (uint) (Numerator / Denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as unsigned 64bit integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>64-Bit unsigned integer</returns>
|
|
||||||
public ulong ToUInt64() {
|
|
||||||
if (IsZero) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (ulong) (Numerator / Denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as BigInteger.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>BigInteger</returns>
|
|
||||||
public BigInteger ToBigInteger() {
|
|
||||||
if (IsZero) {
|
|
||||||
return BigInteger.Zero;
|
|
||||||
}
|
|
||||||
return Numerator / Denominator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as (rounded!) decimal value.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Decimal value</returns>
|
|
||||||
public decimal ToDecimal() {
|
|
||||||
if (IsZero) {
|
|
||||||
return decimal.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_numerator >= MIN_DECIMAL && _numerator <= MAX_DECIMAL && _denominator >= MIN_DECIMAL && _denominator <= MAX_DECIMAL) {
|
|
||||||
return (decimal) _numerator / (decimal) _denominator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// numerator or denominator is too big. Lets try to split the calculation..
|
|
||||||
// Possible OverFlowException!
|
|
||||||
var withoutDecimalPlaces = (decimal) (_numerator / _denominator);
|
|
||||||
|
|
||||||
var remainder = _numerator % _denominator;
|
|
||||||
var lowpart = remainder * BigInteger.Pow(10, 28) / _denominator;
|
|
||||||
var decimalPlaces = (decimal) lowpart / (decimal) Math.Pow(10, 28);
|
|
||||||
|
|
||||||
return withoutDecimalPlaces + decimalPlaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as (rounded!) floating point value.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A floating point value</returns>
|
|
||||||
public double ToDouble() {
|
|
||||||
if (IsZero) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (double) Numerator / (double) Denominator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests if the calculated value of this fraction equals to the calculated value of <paramref name="other"/>.
|
|
||||||
/// It does not matter if either of them is not normalized. Both values will be reduced (normalized) before performing
|
|
||||||
/// the <see cref="object.Equals(object)"/> test.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">The fraction to compare with.</param>
|
|
||||||
/// <returns><c>true</c> if both values are equivalent. (e.g. 2/4 is equivalent to 1/2. But 2/4 is not equivalent to -1/2)</returns>
|
|
||||||
|
|
||||||
public bool IsEquivalentTo(Fraction other) {
|
|
||||||
var a = Reduce();
|
|
||||||
var b = other.Reduce();
|
|
||||||
|
|
||||||
return a.Equals(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Performs an exact comparison with <paramref name="other"/> using numerator and denominator.</para>
|
|
||||||
/// <para>Warning: 1/2 is NOT equal to 2/4! -1/2 is NOT equal to 1/-2!</para>
|
|
||||||
/// <para>If you want to test the calculated values for equality use <see cref="CompareTo(Fraction)"/> or
|
|
||||||
/// <see cref="IsEquivalentTo"/> </para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">The fraction to compare with.</param>
|
|
||||||
/// <returns><c>true</c> if numerator and denominator of both fractions are equal.</returns>
|
|
||||||
|
|
||||||
public bool Equals(Fraction other) {
|
|
||||||
return other._denominator.Equals(_denominator) && other._numerator.Equals(_numerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Performs an exact comparison with <paramref name="other"/> using numerator and denominator.</para>
|
|
||||||
/// <para>Warning: 1/2 is NOT equal to 2/4! -1/2 is NOT equal to 1/-2!</para>
|
|
||||||
/// <para>If you want to test the calculated values for equality use <see cref="CompareTo(Fraction)"/> or
|
|
||||||
/// <see cref="IsEquivalentTo"/> </para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">The fraction to compare with.</param>
|
|
||||||
/// <returns><c>true</c> if <paramref name="other"/> is type of <see cref="Fraction"/> and numerator and denominator of both are equal.</returns>
|
|
||||||
|
|
||||||
public override bool Equals(object other) {
|
|
||||||
if (ReferenceEquals(null, other)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return other is Fraction && Equals((Fraction)other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the hash code.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// A 32bit integer with sign. It has been constructed using the <see cref="Numerator"/> and the <see cref="Denominator"/>.
|
|
||||||
/// </returns>
|
|
||||||
/// <filterpriority>2</filterpriority>
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
unchecked {
|
|
||||||
return (_denominator.GetHashCode() * 397) ^ _numerator.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction {
|
|
||||||
/// <summary>
|
|
||||||
/// Calculates the remainder of the division with the fraction's value and the supplied <paramref name="divisor"/> (% operator).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="divisor">Divisor</param>
|
|
||||||
/// <returns>The remainder (left over)</returns>
|
|
||||||
public Fraction Remainder(Fraction divisor) {
|
|
||||||
if (divisor.IsZero) {
|
|
||||||
throw new DivideByZeroException();
|
|
||||||
}
|
|
||||||
if (IsZero) {
|
|
||||||
return _zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
var gcd = BigInteger.GreatestCommonDivisor(_denominator, divisor.Denominator);
|
|
||||||
|
|
||||||
var thisMultiplier = BigInteger.Divide(_denominator, gcd);
|
|
||||||
var otherMultiplier = BigInteger.Divide(divisor.Denominator, gcd);
|
|
||||||
|
|
||||||
var leastCommonMultiple = BigInteger.Multiply(thisMultiplier, divisor.Denominator);
|
|
||||||
|
|
||||||
var a = BigInteger.Multiply(_numerator, otherMultiplier);
|
|
||||||
var b = BigInteger.Multiply(divisor.Numerator, thisMultiplier);
|
|
||||||
|
|
||||||
var remainder = BigInteger.Remainder(a, b);
|
|
||||||
|
|
||||||
return new Fraction(remainder, leastCommonMultiple);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds the fraction's value with <paramref name="summand"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="summand">Summand</param>
|
|
||||||
/// <returns>The result as summation.</returns>
|
|
||||||
|
|
||||||
public Fraction Add(Fraction summand) {
|
|
||||||
if (_denominator == summand.Denominator) {
|
|
||||||
return new Fraction(BigInteger.Add(_numerator, summand.Numerator), _denominator, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsZero) {
|
|
||||||
// 0 + b = b
|
|
||||||
return summand;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (summand.IsZero) {
|
|
||||||
// a + 0 = a
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
var gcd = BigInteger.GreatestCommonDivisor(_denominator, summand.Denominator);
|
|
||||||
|
|
||||||
var thisMultiplier = BigInteger.Divide(_denominator, gcd);
|
|
||||||
var otherMultiplier = BigInteger.Divide(summand.Denominator, gcd);
|
|
||||||
|
|
||||||
var leastCommonMultiple = BigInteger.Multiply(thisMultiplier, summand.Denominator);
|
|
||||||
|
|
||||||
var calculatedNumerator = BigInteger.Add(
|
|
||||||
BigInteger.Multiply(_numerator, otherMultiplier),
|
|
||||||
BigInteger.Multiply(summand.Numerator, thisMultiplier)
|
|
||||||
);
|
|
||||||
|
|
||||||
return new Fraction(calculatedNumerator, leastCommonMultiple, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Subtracts the fraction's value (minuend) with <paramref name="subtrahend"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="subtrahend">Subtrahend.</param>
|
|
||||||
/// <returns>The result as difference.</returns>
|
|
||||||
|
|
||||||
public Fraction Subtract(Fraction subtrahend) {
|
|
||||||
return Add(subtrahend.Invert());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Inverts the fraction. Has the same result as multiplying it by -1.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The inverted fraction.</returns>
|
|
||||||
|
|
||||||
public Fraction Invert() {
|
|
||||||
if (IsZero) {
|
|
||||||
return _zero;
|
|
||||||
}
|
|
||||||
return new Fraction(BigInteger.Negate(_numerator), _denominator, _state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Multiply the fraction's value by <paramref name="factor"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="factor">Factor</param>
|
|
||||||
/// <returns>The result as product.</returns>
|
|
||||||
|
|
||||||
public Fraction Multiply(Fraction factor) {
|
|
||||||
return new Fraction(
|
|
||||||
_numerator * factor._numerator,
|
|
||||||
_denominator * factor._denominator,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Divides the fraction's value by <paramref name="divisor"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="divisor">Divisor</param>
|
|
||||||
/// <returns>The result as quotient.</returns>
|
|
||||||
|
|
||||||
public Fraction Divide(Fraction divisor) {
|
|
||||||
if (divisor.IsZero) {
|
|
||||||
throw new DivideByZeroException(string.Format("{0} shall be divided by zero.", this));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Fraction(
|
|
||||||
numerator: _numerator * divisor._denominator,
|
|
||||||
denominator: _denominator * divisor._numerator,
|
|
||||||
normalize: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns this as reduced/simplified fraction. The fraction's sign will be normalized.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A reduced and normalized fraction.</returns>
|
|
||||||
|
|
||||||
public Fraction Reduce() {
|
|
||||||
return _state == FractionState.IsNormalized
|
|
||||||
? this
|
|
||||||
: GetReducedFraction(_numerator, _denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the absolute value of a <see cref="Fraction"/> object.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The absolute value.</returns>
|
|
||||||
|
|
||||||
public Fraction Abs() {
|
|
||||||
return Abs(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the absolute value of a <see cref="Fraction"/> object.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fraction">The fraction.</param>
|
|
||||||
/// <returns>The absolute value.</returns>
|
|
||||||
|
|
||||||
public static Fraction Abs(Fraction fraction) {
|
|
||||||
return new Fraction(BigInteger.Abs(fraction.Numerator), BigInteger.Abs(fraction.Denominator), fraction.State);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a reduced and normalized fraction.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="numerator">Numerator</param>
|
|
||||||
/// <param name="denominator">Denominator</param>
|
|
||||||
/// <returns>A reduced and normalized fraction</returns>
|
|
||||||
|
|
||||||
public static Fraction GetReducedFraction(BigInteger numerator, BigInteger denominator) {
|
|
||||||
if (numerator.IsZero || denominator.IsZero) {
|
|
||||||
return Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (denominator.Sign == -1) {
|
|
||||||
// Denominator must not be negative after normalization
|
|
||||||
numerator = BigInteger.Negate(numerator);
|
|
||||||
denominator = BigInteger.Negate(denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
var gcd = BigInteger.GreatestCommonDivisor(numerator, denominator);
|
|
||||||
if (!gcd.IsOne && !gcd.IsZero) {
|
|
||||||
return new Fraction(BigInteger.Divide(numerator, gcd), BigInteger.Divide(denominator, gcd),
|
|
||||||
FractionState.IsNormalized);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Fraction(numerator, denominator, FractionState.IsNormalized);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a fraction raised to the specified power.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="base">base to be raised to a power</param>
|
|
||||||
/// <param name="exponent">A number that specifies a power (exponent)</param>
|
|
||||||
/// <returns>The fraction <paramref name="base"/> raised to the power <paramref name="exponent"/>.</returns>
|
|
||||||
|
|
||||||
public static Fraction Pow(Fraction @base, int exponent) {
|
|
||||||
return exponent < 0
|
|
||||||
? Pow(new Fraction(@base._denominator, @base._numerator), -exponent)
|
|
||||||
: new Fraction(BigInteger.Pow(@base._numerator, exponent), BigInteger.Pow(@base._denominator, exponent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction {
|
|
||||||
#pragma warning disable 1591
|
|
||||||
public static bool operator ==(Fraction left, Fraction right) {
|
|
||||||
return left.Equals(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(Fraction left, Fraction right) {
|
|
||||||
return !left.Equals(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Fraction operator +(Fraction a, Fraction b) {
|
|
||||||
return a.Add(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Fraction operator -(Fraction a, Fraction b) {
|
|
||||||
return a.Subtract(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Fraction operator *(Fraction a, Fraction b) {
|
|
||||||
return a.Multiply(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Fraction operator /(Fraction a, Fraction b) {
|
|
||||||
return a.Divide(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Fraction operator %(Fraction a, Fraction b) {
|
|
||||||
return a.Remainder(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <(Fraction a, Fraction b) {
|
|
||||||
return a.CompareTo(b) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >(Fraction a, Fraction b) {
|
|
||||||
return a.CompareTo(b) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=(Fraction a, Fraction b) {
|
|
||||||
return a.CompareTo(b) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=(Fraction a, Fraction b) {
|
|
||||||
return a.CompareTo(b) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Fraction(int value) {
|
|
||||||
return new Fraction(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Fraction(long value) {
|
|
||||||
return new Fraction(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Fraction(uint value) {
|
|
||||||
return new Fraction(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Fraction(ulong value) {
|
|
||||||
return new Fraction(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Fraction(BigInteger value) {
|
|
||||||
return new Fraction(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator Fraction(double value) {
|
|
||||||
return new Fraction(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator Fraction(decimal value) {
|
|
||||||
return new Fraction(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator Fraction(string value) {
|
|
||||||
return FromString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator int(Fraction fraction) {
|
|
||||||
return fraction.ToInt32();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator long(Fraction fraction) {
|
|
||||||
return fraction.ToInt64();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator uint(Fraction fraction) {
|
|
||||||
return fraction.ToUInt32();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator ulong(Fraction fraction) {
|
|
||||||
return fraction.ToUInt64();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator decimal(Fraction fraction) {
|
|
||||||
return fraction.ToDecimal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator double(Fraction fraction) {
|
|
||||||
return fraction.ToDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator BigInteger(Fraction fraction) {
|
|
||||||
return fraction.ToBigInteger();
|
|
||||||
}
|
|
||||||
#pragma warning restore 1591
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
using k8s.Internal.Fractions.Formatter;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
internal partial struct Fraction {
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the fraction as "numerator/denominator" or just "numerator" if the denominator has a value of 1.
|
|
||||||
/// The returning value is culture invariant (<see cref="CultureInfo" />).
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>"numerator/denominator" or just "numerator"</returns>
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return ToString("G", DefaultFractionFormatProvider.Instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Formats the value of the current instance using the specified format.
|
|
||||||
/// The returning value is culture invariant (<see cref="CultureInfo" />).
|
|
||||||
/// See <see cref="ToString(string,IFormatProvider)"/> for all formatting options.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>"numerator/denominator" or just "numerator"</returns>
|
|
||||||
|
|
||||||
public string ToString(string format) {
|
|
||||||
return ToString(format, DefaultFractionFormatProvider.Instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Formats the value of the current instance using the specified format. The numbers are however culture invariant.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The value of the current instance in the specified format.
|
|
||||||
/// </returns>
|
|
||||||
/// <param name="format">The format to use.
|
|
||||||
/// <list type="table">
|
|
||||||
/// <listheader><term>symbol</term><description>description</description></listheader>
|
|
||||||
/// <item><term>G</term><description>General format: numerator/denominator</description></item>
|
|
||||||
/// <item><term>n</term><description>Numerator</description></item>
|
|
||||||
/// <item><term>d</term><description>Denominator</description></item>
|
|
||||||
/// <item><term>z</term><description>The fraction as integer</description></item>
|
|
||||||
/// <item><term>r</term><description>The positive remainder of all digits after the decimal point using the format: numerator/denominator or <see cref="string.Empty"/> if the fraction is a valid integer without digits after the decimal point.</description></item>
|
|
||||||
/// <item><term>m</term><description>The fraction as mixed number e.g. "2 1/3" instead of "7/3"</description></item>
|
|
||||||
/// </list>
|
|
||||||
/// -or- A null reference (Nothing in Visual Basic) to use the default format defined for the type of the <see cref="T:System.IFormattable"/> implementation. </param>
|
|
||||||
/// <param name="formatProvider">The provider to use to format the value. -or- A null reference (Nothing in Visual Basic) to obtain the numeric format information from the current locale setting of the operating system.</param>
|
|
||||||
/// <filterpriority>2</filterpriority>
|
|
||||||
public string ToString(string format, IFormatProvider formatProvider) {
|
|
||||||
var formatter = formatProvider?.GetFormat(GetType()) as ICustomFormatter;
|
|
||||||
|
|
||||||
return formatter != null
|
|
||||||
? formatter.Format(format, this, formatProvider)
|
|
||||||
: DefaultFractionFormatter.Instance.Format(format, this, formatProvider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Numerics;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using k8s.Internal.Fractions.TypeConverters;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
/// <summary>
|
|
||||||
/// A mathematical fraction. A rational number written as a/b (a is the numerator and b the denominator).
|
|
||||||
/// The data type is not capable to store NaN (not a number) or infinite.
|
|
||||||
/// </summary>
|
|
||||||
[TypeConverter(typeof (FractionTypeConverter))]
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
internal partial struct Fraction : IEquatable<Fraction>, IComparable, IComparable<Fraction>, IFormattable {
|
|
||||||
private static readonly BigInteger MIN_DECIMAL = new BigInteger(decimal.MinValue);
|
|
||||||
private static readonly BigInteger MAX_DECIMAL = new BigInteger(decimal.MaxValue);
|
|
||||||
private static readonly Fraction _zero = new Fraction(BigInteger.Zero, BigInteger.Zero, FractionState.IsNormalized);
|
|
||||||
private static readonly Fraction _one = new Fraction(BigInteger.One, BigInteger.One, FractionState.IsNormalized);
|
|
||||||
private static readonly Fraction _minus_one = new Fraction(BigInteger.MinusOne, BigInteger.One, FractionState.IsNormalized);
|
|
||||||
|
|
||||||
private readonly BigInteger _denominator;
|
|
||||||
private readonly BigInteger _numerator;
|
|
||||||
private readonly FractionState _state;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The numerator.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public BigInteger Numerator => _numerator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The denominator
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public BigInteger Denominator => _denominator;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <c>true</c> if the value is positive (greater than or equal to 0).
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public bool IsPositive => _numerator.Sign == 1 && _denominator.Sign == 1 ||
|
|
||||||
_numerator.Sign == -1 && _denominator.Sign == -1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <c>true</c> if the value is negative (lesser than 0).
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public bool IsNegative => _numerator.Sign == -1 && _denominator.Sign == 1 ||
|
|
||||||
_numerator.Sign == 1 && _denominator.Sign == -1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <c>true</c> if the fraction has a real (calculated) value of 0.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public bool IsZero => _numerator.IsZero || _denominator.IsZero;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The fraction's state.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public FractionState State => _state;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A fraction with the reduced/simplified value of 0.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public static Fraction Zero => _zero;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A fraction with the reduced/simplified value of 1.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public static Fraction One => _one;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A fraction with the reduced/simplified value of -1.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public static Fraction MinusOne => _minus_one;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
namespace k8s.Internal.Fractions {
|
|
||||||
/// <summary>
|
|
||||||
/// The fraction's state.
|
|
||||||
/// </summary>
|
|
||||||
internal enum FractionState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Unknown state.
|
|
||||||
/// </summary>
|
|
||||||
Unknown,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A reduced/simplified fraction.
|
|
||||||
/// </summary>
|
|
||||||
IsNormalized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions {
|
|
||||||
/// <summary>
|
|
||||||
/// Exception that will be thrown if an argument contains not a number (NaN) or is infinite.
|
|
||||||
/// </summary>
|
|
||||||
internal class InvalidNumberException : ArithmeticException {
|
|
||||||
#pragma warning disable 1591
|
|
||||||
public InvalidNumberException() {}
|
|
||||||
public InvalidNumberException(string message) : base(message) {}
|
|
||||||
public InvalidNumberException(string message, Exception innerException) : base(message, innerException) {}
|
|
||||||
#pragma warning restore 1591
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
This is a copy of the Fractions library.
|
|
||||||
Original source code is [here](https://github.com/danm-de/Fractions), licensed under the BSD license.
|
|
||||||
|
|
||||||
The source has been vendored into this project in order to produce a fully strongly-named assembly.
|
|
||||||
As of the time that this file was created, no strongly-named assembly for the Fractions library existed.
|
|
||||||
By including the source code in this project, we can produce a strongly-named assembly for the KubernetesClient.
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace k8s.Internal.Fractions.TypeConverters {
|
|
||||||
/// <summary>
|
|
||||||
/// Converts the <see cref="Fraction"/> from / to various data types.
|
|
||||||
/// </summary>
|
|
||||||
internal sealed class FractionTypeConverter : TypeConverter {
|
|
||||||
private static readonly HashSet<Type> SUPPORTED_TYPES = new HashSet<Type> {
|
|
||||||
typeof (string),
|
|
||||||
typeof (int),
|
|
||||||
typeof (long),
|
|
||||||
typeof (decimal),
|
|
||||||
typeof (double),
|
|
||||||
typeof (Fraction),
|
|
||||||
typeof (BigInteger)
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly Dictionary<Type, Func<object, CultureInfo, object>> CONVERT_TO_DICTIONARY =
|
|
||||||
new Dictionary<Type, Func<object, CultureInfo, object>> {
|
|
||||||
{typeof (string), (o, info) => ((Fraction) o).ToString()},
|
|
||||||
{typeof (int), (o, info) => ((Fraction) o).ToInt32()},
|
|
||||||
{typeof (long), (o, info) => ((Fraction) o).ToInt64()},
|
|
||||||
{typeof (decimal), (o, info) => ((Fraction) o).ToDecimal()},
|
|
||||||
{typeof (double), (o, info) => ((Fraction) o).ToDouble()},
|
|
||||||
{typeof (Fraction), (o, info) => (Fraction) o},
|
|
||||||
{typeof (BigInteger), (o, info) => ((Fraction) o).ToBigInteger()}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly Dictionary<Type, Func<object, CultureInfo, Fraction>> CONVERT_FROM_DICTIONARY =
|
|
||||||
new Dictionary<Type, Func<object, CultureInfo, Fraction>> {
|
|
||||||
{typeof (string), (o, info) => Fraction.FromString((string) o, info)},
|
|
||||||
{typeof (int), (o, info) => new Fraction((int) o)},
|
|
||||||
{typeof (long), (o, info) => new Fraction((long) o)},
|
|
||||||
{typeof (decimal), (o, info) => Fraction.FromDecimal((decimal) o)},
|
|
||||||
{typeof (double), (o, info) => Fraction.FromDouble((double) o)},
|
|
||||||
{typeof (Fraction), (o, info) => (Fraction) o},
|
|
||||||
{typeof (BigInteger), (o, info) => new Fraction((BigInteger) o)}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether the type converter can convert an object to the specified type.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">An object that provides a format context.</param>
|
|
||||||
/// <param name="destinationType">The type you want to convert to.</param>
|
|
||||||
/// <returns><c>true</c> if this converter can perform the conversion; otherwise, <c>false</c>.</returns>
|
|
||||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
|
|
||||||
return SUPPORTED_TYPES.Contains(destinationType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">An <see cref="ITypeDescriptorContext "/>that provides a format context. </param>
|
|
||||||
/// <param name="sourceType">A <see cref="Type"/> that represents the type you want to convert from. </param>
|
|
||||||
/// <returns><c>true</c>if this converter can perform the conversion; otherwise, <c>false</c>.</returns>
|
|
||||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
|
|
||||||
return SUPPORTED_TYPES.Contains(sourceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts the given value object to the specified type, using the specified context and culture information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">An <see cref="ITypeDescriptorContext" /> that provides a format context.</param>
|
|
||||||
/// <param name="culture">A CultureInfo. If <c>null</c> is passed, the current culture is assumed.</param>
|
|
||||||
/// <param name="value">The <see cref="Object"/> to convert.</param>
|
|
||||||
/// <param name="destinationType">The <see cref="Type" /> to convert the value parameter to.</param>
|
|
||||||
/// <returns>An <see cref="Object"/> that represents the converted value.</returns>
|
|
||||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,
|
|
||||||
Type destinationType) {
|
|
||||||
return !ReferenceEquals(value, null) && CONVERT_TO_DICTIONARY.TryGetValue(destinationType, out Func<object, CultureInfo, object> func)
|
|
||||||
? func(value, culture)
|
|
||||||
: base.ConvertTo(context, culture, value, destinationType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts the given object to the type of this converter, using the specified context and culture information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">An <see cref="ITypeDescriptorContext"/> that provides a format context.</param>
|
|
||||||
/// <param name="culture">The <see cref="CultureInfo"/> to use as the current culture.</param>
|
|
||||||
/// <param name="value">The <see cref="Object"/> to convert.</param>
|
|
||||||
/// <returns>An <see cref="Object"/> that represents the converted value.</returns>
|
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
|
|
||||||
if (ReferenceEquals(value, null)) {
|
|
||||||
return Fraction.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CONVERT_FROM_DICTIONARY.TryGetValue(value.GetType(), out Func<object, CultureInfo, Fraction> func)
|
|
||||||
? func(value, culture)
|
|
||||||
: base.ConvertFrom(context, culture, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2013-2017, Daniel Mueller <daniel@danm.de>
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Fractions" Version="4.0.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="1.1.2" Condition="'$(TargetFramework)' != 'netstandard2.0' and '$(TargetFramework)' != 'netcoreapp2.1'" />
|
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="1.1.2" Condition="'$(TargetFramework)' != 'netstandard2.0' and '$(TargetFramework)' != 'netcoreapp2.1'" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp2.1'" />
|
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp2.1'" />
|
||||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.50" PrivateAssets="all" />
|
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.50" PrivateAssets="all" />
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using k8s.Internal.Fractions;
|
using Fractions;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using YamlDotNet.Core;
|
using YamlDotNet.Core;
|
||||||
using YamlDotNet.Core.Events;
|
using YamlDotNet.Core.Events;
|
||||||
|
|||||||
Reference in New Issue
Block a user