Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Rationals/Formatting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@
/// <param name="formatProvider">Ignored, custom format providers are not supported</param>
public string ToString(string format, IFormatProvider formatProvider) => ToString(format);

#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER

/// <summary>Tries to format the value of the current instance into the provided span of characters.</summary>
/// <param name="destination">When this method returns, this instance's value formatted as a span of characters.</param>
/// <param name="charsWritten">When this method returns, the number of characters that were written in <paramref name="destination"/>.</param>
/// <param name="format">A span containing the characters that represent a standard or custom format string that defines the acceptable format for <paramref name="destination"/>.</param>
/// <param name="provider">An optional object that supplies culture-specific formatting information for <paramref name="destination"/>.</param>
/// <returns><see langword="true"/> if the formatting was successful; otherwise, <see langword="false"/>.</returns>
/// <remarks>
/// An implementation of this interface should produce the same string of characters as an implementation of <see cref="IFormattable.ToString(string?, IFormatProvider?)"/>
/// on the same type.
/// TryFormat should return false only if there is not enough space in the destination buffer. Any other failures should throw an exception.
/// </remarks>
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider provider)
=> throw new NotImplementedException();

Check warning on line 79 in src/Rationals/Formatting.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Formatting.cs#L79

Added line #L79 was not covered by tests

#endif

/// <summary>
/// Formats rational number to string
/// </summary>
Expand Down
189 changes: 189 additions & 0 deletions src/Rationals/GenericMath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using System;
using System.Numerics;

#if NET7_0_OR_GREATER

namespace Rationals
{
public partial struct Rational : INumber<Rational>
{
/// <inheritdoc />
static Rational INumberBase<Rational>.One
=> One;

/// <inheritdoc />
static int INumberBase<Rational>.Radix
=> 2;

/// <inheritdoc />
static Rational INumberBase<Rational>.Zero
=> Zero;

/// <inheritdoc />
static Rational IAdditiveIdentity<Rational, Rational>.AdditiveIdentity
=> Zero;

/// <inheritdoc />
static Rational IMultiplicativeIdentity<Rational, Rational>.MultiplicativeIdentity
=> One;

/// <inheritdoc />
static bool INumberBase<Rational>.IsCanonical(Rational value)
{
var canonical = value.CanonicalForm;
return value.Numerator == canonical.Numerator && value.Denominator == canonical.Denominator;
}

/// <inheritdoc />
static bool INumberBase<Rational>.IsComplexNumber(Rational value)
=> false;

/// <inheritdoc />
static bool INumberBase<Rational>.IsEvenInteger(Rational value)
{
var canonical = value.CanonicalForm;
return canonical.Denominator.IsOne && canonical.Numerator.IsEven;
}

/// <inheritdoc />
static bool INumberBase<Rational>.IsFinite(Rational value)
=> true;

/// <inheritdoc />
static bool INumberBase<Rational>.IsImaginaryNumber(Rational value)
=> false;

/// <inheritdoc />
static bool INumberBase<Rational>.IsInfinity(Rational value)
=> false;

/// <inheritdoc />
static bool INumberBase<Rational>.IsInteger(Rational value)
=> value.CanonicalForm.Denominator.IsOne;

/// <inheritdoc />
static bool INumberBase<Rational>.IsNaN(Rational value)
=> value.IsNaN;

/// <inheritdoc />
static bool INumberBase<Rational>.IsNegative(Rational value)
=> value.Sign < 0;

/// <inheritdoc />
static bool INumberBase<Rational>.IsNegativeInfinity(Rational value)
=> false;

/// <inheritdoc />
static bool INumberBase<Rational>.IsNormal(Rational value)
=> !value.IsZero && !value.IsNaN;

/// <inheritdoc />
static bool INumberBase<Rational>.IsOddInteger(Rational value)
{
var canonical = value.CanonicalForm;
return canonical.Denominator.IsOne && !canonical.Numerator.IsEven;
}

/// <inheritdoc />
static bool INumberBase<Rational>.IsPositive(Rational value)
=> value.Sign > 0;

/// <inheritdoc />
static bool INumberBase<Rational>.IsPositiveInfinity(Rational value)
=> false;

/// <inheritdoc />
static bool INumberBase<Rational>.IsRealNumber(Rational value)
=> true;

/// <inheritdoc />
static bool INumberBase<Rational>.IsSubnormal(Rational value)
=> false;

/// <inheritdoc />
static bool INumberBase<Rational>.IsZero(Rational value)
=> value.IsZero;

private static Rational MaxMagnitudeInner(Rational x, Rational y)
{
if (x.IsNaN)
return NaN;

if (y.IsNaN)
return NaN;

var ax = Abs(x);
var ay = Abs(y);

if (ax > ay)
return x;

if (ax == ay)
return x.Sign < 0 ? y : x;

return y;
}

private static Rational MinMagnitudeInner(Rational x, Rational y)
{
if (x.IsNaN)
return NaN;

if (y.IsNaN)
return NaN;

var ax = Abs(x);
var ay = Abs(y);

if (ax < ay)
return x;

if (ax == ay)
return x.Sign < 0 ? x : y;

return y;
}

/// <inheritdoc />
static Rational INumberBase<Rational>.MaxMagnitude(Rational x, Rational y)
=> MaxMagnitudeInner(x, y);

/// <inheritdoc />
static Rational INumberBase<Rational>.MaxMagnitudeNumber(Rational x, Rational y)
=> MaxMagnitudeInner(x, y);

/// <inheritdoc />
static Rational INumberBase<Rational>.MinMagnitude(Rational x, Rational y)
=> MinMagnitudeInner(x, y);

/// <inheritdoc />
static Rational INumberBase<Rational>.MinMagnitudeNumber(Rational x, Rational y)
=> MinMagnitudeInner(x, y);

/// <inheritdoc />
static bool INumberBase<Rational>.TryConvertFromChecked<TOther>(TOther value, out Rational result)
=> throw new NotImplementedException();

/// <inheritdoc />
static bool INumberBase<Rational>.TryConvertFromSaturating<TOther>(TOther value, out Rational result)
=> throw new NotImplementedException();

/// <inheritdoc />
static bool INumberBase<Rational>.TryConvertFromTruncating<TOther>(TOther value, out Rational result)
=> throw new NotImplementedException();

/// <inheritdoc />
static bool INumberBase<Rational>.TryConvertToChecked<TOther>(Rational value, out TOther result)
=> throw new NotImplementedException();

/// <inheritdoc />
static bool INumberBase<Rational>.TryConvertToSaturating<TOther>(Rational value, out TOther result)
=> throw new NotImplementedException();

/// <inheritdoc />
static bool INumberBase<Rational>.TryConvertToTruncating<TOther>(Rational value, out TOther result)
=> throw new NotImplementedException();
}
}

#endif
18 changes: 16 additions & 2 deletions src/Rationals/Operators.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Rationals
using System;

namespace Rationals
{
/// <summary>
/// Rational number.
Expand Down Expand Up @@ -69,5 +71,17 @@
/// Overload of the &gt;= operator.
/// </summary>
public static bool operator >=(Rational left, Rational right) => !left.IsNaN && !right.IsNaN && left.CompareTo(right) >= 0;

/// <summary>
/// Overload of the % operator.
/// </summary>
public static Rational operator %(Rational left, Rational right)
=> throw new NotImplementedException();

Check warning on line 79 in src/Rationals/Operators.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Operators.cs#L79

Added line #L79 was not covered by tests

/// <summary>
/// Overload of the unary + operator.
/// </summary>
public static Rational operator +(Rational value)
=> new(+value.Denominator, +value.Numerator);

Check warning on line 85 in src/Rationals/Operators.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Operators.cs#L85

Added line #L85 was not covered by tests
}
}
}
40 changes: 40 additions & 0 deletions src/Rationals/Parsing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@
return Parse(value, style, NumberFormatInfo.GetInstance(provider));
}


#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER

/// <inheritdoc cref="Parse(string)"/>
[SuppressMessage("ReSharper", "UnusedMember.Global")]
public static Rational Parse(ReadOnlySpan<char> value, IFormatProvider provider)
{
return Parse(value, NumberStyles.Float, NumberFormatInfo.GetInstance(provider));

Check warning on line 62 in src/Rationals/Parsing.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Parsing.cs#L62

Added line #L62 was not covered by tests
}

/// <inheritdoc cref="Parse(string)"/>
[SuppressMessage("ReSharper", "UnusedMember.Global")]
public static Rational Parse(ReadOnlySpan<char> value, NumberStyles style, IFormatProvider provider)
=> Parse(value.ToString(), style, NumberFormatInfo.GetInstance(provider));

Check warning on line 68 in src/Rationals/Parsing.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Parsing.cs#L68

Added line #L68 was not covered by tests

#endif

private static Rational Parse(string value, NumberStyles style, NumberFormatInfo info)
{
if (!TryParse(value, style, info, out var result))
Expand All @@ -74,6 +91,29 @@
return TryParse(value, style, NumberFormatInfo.GetInstance(provider), out result);
}

/// <inheritdoc cref="Parse(string)"/>
[SuppressMessage("ReSharper", "UnusedMember.Global")]
public static bool TryParse(string value, IFormatProvider provider, out Rational result)
{
return TryParse(value, NumberStyles.Float, NumberFormatInfo.GetInstance(provider), out result);

Check warning on line 98 in src/Rationals/Parsing.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Parsing.cs#L98

Added line #L98 was not covered by tests
}

#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER

/// <inheritdoc cref="Parse(string)"/>
[SuppressMessage("ReSharper", "UnusedMember.Global")]
public static bool TryParse(ReadOnlySpan<char> value, IFormatProvider provider, out Rational result)
{
return TryParse(value, NumberStyles.Float, NumberFormatInfo.GetInstance(provider), out result);

Check warning on line 107 in src/Rationals/Parsing.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Parsing.cs#L107

Added line #L107 was not covered by tests
}

/// <inheritdoc cref="Parse(string)"/>
[SuppressMessage("ReSharper", "UnusedMember.Global")]
public static bool TryParse(ReadOnlySpan<char> value, NumberStyles style, IFormatProvider provider, out Rational result)
=> TryParse(value.ToString(), style, NumberFormatInfo.GetInstance(provider), out result);

Check warning on line 113 in src/Rationals/Parsing.cs

View check run for this annotation

Codecov / codecov/patch

src/Rationals/Parsing.cs#L113

Added line #L113 was not covered by tests

#endif

private static bool TryParse(string value, NumberStyles style, NumberFormatInfo info, out Rational result)
{
result = default;
Expand Down
4 changes: 2 additions & 2 deletions src/Rationals/Rationals.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup Label="Basic build">
<TargetFrameworks>netstandard1.3;net40;</TargetFrameworks>
<LangVersion>7.3</LangVersion>
<TargetFrameworks>net7.0;netstandard2.1;netstandard1.3;net40</TargetFrameworks>
<LangVersion>11</LangVersion>
<Deterministic>true</Deterministic>
</PropertyGroup>

Expand Down