Skip to content

Commit

Permalink
Various improvements to Rational processing
Browse files Browse the repository at this point in the history
  • Loading branch information
drewnoakes committed May 5, 2022
1 parent 236a5e5 commit 64c507f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 58 deletions.
86 changes: 38 additions & 48 deletions MetadataExtractor.Tests/RationalTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,16 @@ public void ToSimpleString()
var third1 = new Rational(1, 3);
var third2 = new Rational(2, 6);
Assert.Equal("1/3", third1.ToSimpleString());
Assert.Equal("1/3", third2.ToSimpleString());
Assert.Equal("1/3", third2.ToSimpleString(allowDecimal: false));
Assert.Equal(third1, third2);

var twoThirds = new Rational(10, 15);
Assert.Equal("2/3", twoThirds.ToSimpleString());
Assert.Equal("2/3", twoThirds.ToSimpleString(allowDecimal: false));

var twoSixths = new Rational(2, 6);
Assert.Equal("1/3", twoSixths.ToSimpleString());
Assert.Equal("1/3", twoSixths.ToSimpleString(allowDecimal: false));

var two = new Rational(10, 5);
Assert.True(two.IsInteger);
Expand Down Expand Up @@ -242,63 +247,48 @@ public void EqualsExactMethod()
[Fact]
public void SimplifiedInstances()
{
var simple = new Rational(1, 2);
Test(n => new Rational(n, 2 * n), new Rational(1, 2));
Test(n => new Rational(2 * n, n), new Rational(2, 1));
Test(n => new Rational(-n, 2 * n), new Rational(-1, 2));
Test(n => new Rational(n, -2 * n), new Rational(-1, 2));
Test(n => new Rational(-n, -2 * n), new Rational(1, 2));

foreach (var prime in _primes)
static void Test(Func<ushort, Rational> create, Rational expected)
{
var complex = new Rational(prime, 2 * prime);
var actualSimple = complex.GetSimplifiedInstance();

Assert.True(simple.EqualsExact(actualSimple), $"Complex {complex}, Expected simple {simple}, Actual simple {actualSimple}");
Assert.Equal(actualSimple.ToDecimal(), complex.ToDecimal());
}

simple = new Rational(2, 1);

foreach (var prime in _primes)
{
var complex = new Rational(2 * prime, prime);
var actualSimple = complex.GetSimplifiedInstance();

Assert.True(simple.EqualsExact(actualSimple), $"Complex {complex}, Expected simple {simple}, Actual simple {actualSimple}");
Assert.Equal(actualSimple.ToDecimal(), complex.ToDecimal());
foreach (var prime in _primes)
{
var complex = create(prime);
var actualSimple = complex.GetSimplifiedInstance();

Assert.True(expected.EqualsExact(actualSimple), $"Complex {complex}, Expected simple {expected}, Actual simple {actualSimple}");
Assert.Equal(actualSimple.ToDecimal(), complex.ToDecimal());
}
}

simple = new Rational(-1, 2);

foreach (var prime in _primes)
{
var complex = new Rational(-prime, 2 * prime);
var actualSimple = complex.GetSimplifiedInstance();

Assert.True(simple.EqualsExact(actualSimple), $"Complex {complex}, Expected simple {simple}, Actual simple {actualSimple}");
Assert.Equal(actualSimple.ToDecimal(), complex.ToDecimal());
}

simple = new Rational(1, -2);
Assert.Equal(new Rational(-32768, 65535), new Rational(-32768, 65535).GetSimplifiedInstance());
Assert.Equal(new Rational(-32768, 32767), new Rational(-32768, 32767).GetSimplifiedInstance());
}

foreach (var prime in _primes)
{
var complex = new Rational(prime, -2 * prime);
var actualSimple = complex.GetSimplifiedInstance();
[Fact]
public void GetSimplifiedInstance_FlipsSignsIfNeeded()
{
var r = new Rational(1, -2);

Assert.True(simple.EqualsExact(actualSimple), $"Complex {complex}, Expected simple {simple}, Actual simple {actualSimple}");
Assert.Equal(actualSimple.ToDecimal(), complex.ToDecimal());
}
var s = r.GetSimplifiedInstance();

simple = new Rational(-1, -2);
Assert.Equal(-1, s.Numerator);
Assert.Equal(2, s.Denominator);
}

foreach (var prime in _primes)
{
var complex = new Rational(-prime, -2 * prime);
var actualSimple = complex.GetSimplifiedInstance();
[Fact]
public void GetSimplifiedInstance_RemovesSignsIfNeeded()
{
var r = new Rational(-1, -2);

Assert.True(simple.EqualsExact(actualSimple), $"Complex {complex}, Expected simple {simple}, Actual simple {actualSimple}");
Assert.Equal(actualSimple.ToDecimal(), complex.ToDecimal());
}
var s = r.GetSimplifiedInstance();

Assert.Equal(new Rational(-32768, 65535), new Rational(-32768, 65535).GetSimplifiedInstance());
Assert.Equal(new Rational(-32768, 32767), new Rational(-32768, 32767).GetSimplifiedInstance());
Assert.Equal(1, s.Numerator);
Assert.Equal(2, s.Denominator);
}
}
}
23 changes: 13 additions & 10 deletions MetadataExtractor/Rational.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,10 @@ public string ToSimpleString(bool allowDecimal = true, IFormatProvider? provider
return ToString(provider);

if (IsInteger)
return ToInt32().ToString(provider);

if (Numerator != 1 && Denominator % Numerator == 0)
{
// common factor between denominator and numerator
var newDenominator = Denominator / Numerator;
return new Rational(1, newDenominator).ToSimpleString(allowDecimal, provider);
}
return ToInt64().ToString(provider);

var simplifiedInstance = GetSimplifiedInstance();

if (allowDecimal)
{
var doubleString = simplifiedInstance.ToDouble().ToString(provider);
Expand Down Expand Up @@ -281,9 +275,18 @@ static long GCD(long a, long b)
return a == 0 ? b : a;
}

var gcd = GCD(Numerator, Denominator);
var n = Numerator;
var d = Denominator;

if (d < 0)
{
n = -n;
d = -d;
}

var gcd = GCD(n, d);

return new Rational(Numerator / gcd, Denominator / gcd);
return new Rational(n / gcd, d / gcd);
}

#region Equality operators
Expand Down

0 comments on commit 64c507f

Please sign in to comment.