From 4654924529b3fed06f3900610548ffa7ad4cc239 Mon Sep 17 00:00:00 2001 From: bazzilic Date: Tue, 13 Sep 2022 01:00:28 +0800 Subject: [PATCH] Added Abs method and fixed a bug in fraction comparison when fractions have negative denominator --- .github/workflows/release-dotnet-nuget.yml | 42 ++++----- .github/workflows/test-dotnet-windows.yml | 20 ++--- .gitignore | 1 - .../Aprismatic.BigFraction.csproj | 1 + src/Aprismatic.BigFraction/BigFraction.cs | 61 ++++++------- test/BigFractionTest/BigFractionTest.cs | 88 +++++++++++++++++-- 6 files changed, 139 insertions(+), 74 deletions(-) diff --git a/.github/workflows/release-dotnet-nuget.yml b/.github/workflows/release-dotnet-nuget.yml index b724b17..fa8f93e 100644 --- a/.github/workflows/release-dotnet-nuget.yml +++ b/.github/workflows/release-dotnet-nuget.yml @@ -9,18 +9,16 @@ jobs: runs-on: windows-latest steps: - name: Checkout - uses: actions/checkout@v2 - - name: Setup nuget - uses: nuget/setup-nuget@v1 - - name: Update nuget source + uses: actions/checkout@v3 + - name: Add github packages store as NuGet source run: | - nuget sources update -Name 'github' ` - -Source https://nuget.pkg.github.com/aprismatic/index.json ` - -UserName ${{ secrets.GithubUsername }} ` - -Password ${{ secrets.GithubToken }} ` - -ConfigFile ./nuget.config + dotnet nuget update source github ` + --source https://nuget.pkg.github.com/aprismatic/index.json ` + --username "${{ github.actor }}" ` + --password "${{ github.token }}" ` + --configfile ./nuget.config - name: Restore packages - run: nuget restore + run: dotnet restore - name: Build with dotnet run: dotnet build --configuration Release --no-restore - name: Run tests @@ -31,24 +29,22 @@ jobs: runs-on: windows-latest steps: - name: Checkout - uses: actions/checkout@v2 - - name: Setup nuget - uses: nuget/setup-nuget@v1 - - name: Update nuget source + uses: actions/checkout@v3 + - name: Add github packages store as NuGet source run: | - nuget sources update -Name 'github' ` - -Source https://nuget.pkg.github.com/aprismatic/index.json ` - -UserName ${{ secrets.GithubUsername }} ` - -Password ${{ secrets.GithubToken }} ` - -ConfigFile ./nuget.config + dotnet nuget update source github ` + --source https://nuget.pkg.github.com/aprismatic/index.json ` + --username "${{ github.actor }}" ` + --password "${{ github.token }}" ` + --configfile ./nuget.config - name: Restore packages - run: nuget restore + run: dotnet restore - name: Build with dotnet run: dotnet build --configuration Release --no-restore -p:Version=${{ github.event.release.tag_name }} - name: Pack nuget packages run: dotnet pack --configuration Release --no-build --output nupkgs -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg -p:PackageVersion=${{ github.event.release.tag_name }} - name: Publish nuget packages - run: dotnet nuget push **/*.nupkg --source "github" + run: dotnet nuget push **/*.nupkg --source "github" --skip-duplicate --api-key "${{ github.token }}" - name: Upload artifacts uses: actions/upload-artifact@v1 with: @@ -67,6 +63,6 @@ jobs: - name: Release artifacts uses: skx/github-action-publish-binaries@master env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ github.token }} with: - args: 'nupkgs/*' \ No newline at end of file + args: 'nupkgs/*' diff --git a/.github/workflows/test-dotnet-windows.yml b/.github/workflows/test-dotnet-windows.yml index dac8a4f..4845146 100644 --- a/.github/workflows/test-dotnet-windows.yml +++ b/.github/workflows/test-dotnet-windows.yml @@ -11,19 +11,17 @@ jobs: runs-on: windows-latest steps: - name: Checkout - uses: actions/checkout@v2 - - name: Setup nuget - uses: nuget/setup-nuget@v1 - - name: Update nuget source + uses: actions/checkout@v3 + - name: Add github packages store as NuGet source run: | - nuget sources update -Name 'github' ` - -Source https://nuget.pkg.github.com/aprismatic/index.json ` - -UserName ${{ secrets.GithubUsername }} ` - -Password ${{ secrets.GithubToken }} ` - -ConfigFile ./nuget.config + dotnet nuget update source github ` + --source https://nuget.pkg.github.com/aprismatic/index.json ` + --username "${{ github.actor }}" ` + --password "${{ github.token }}" ` + --configfile ./nuget.config - name: Restore packages - run: nuget restore + run: dotnet restore - name: Build with dotnet run: dotnet build --configuration Release --no-restore - name: Run tests - run: dotnet test --configuration Release --no-build \ No newline at end of file + run: dotnet test --configuration Release --no-build diff --git a/.gitignore b/.gitignore index faf4fb1..71bd359 100644 --- a/.gitignore +++ b/.gitignore @@ -359,7 +359,6 @@ MigrationBackup/ # VS Code .vscode/ - # Common IntelliJ Platform excludes .idea/ diff --git a/src/Aprismatic.BigFraction/Aprismatic.BigFraction.csproj b/src/Aprismatic.BigFraction/Aprismatic.BigFraction.csproj index ef864e2..69c382e 100644 --- a/src/Aprismatic.BigFraction/Aprismatic.BigFraction.csproj +++ b/src/Aprismatic.BigFraction/Aprismatic.BigFraction.csproj @@ -3,6 +3,7 @@ netstandard1.1 BigFraction implementation using .NET BigInteger class. true + https://github.com/aprismatic/bigfraction diff --git a/src/Aprismatic.BigFraction/BigFraction.cs b/src/Aprismatic.BigFraction/BigFraction.cs index a4cb90b..8d20e85 100644 --- a/src/Aprismatic.BigFraction/BigFraction.cs +++ b/src/Aprismatic.BigFraction/BigFraction.cs @@ -22,7 +22,6 @@ public readonly struct BigFraction private static readonly BigInteger MAX_DECIMAL = new BigInteger(decimal.MaxValue); private static readonly BigInteger MIN_DECIMAL = new BigInteger(decimal.MinValue); - /// /// Predefined constant of a BigFraction that represents –1. /// @@ -40,7 +39,7 @@ public readonly struct BigFraction // FIELDS /// - /// Returns the sign of the fraction. + /// Returns the sign of the fraction (-1, 0, or 1). /// public int Sign => Numerator.IsZero ? 0 : @@ -58,6 +57,7 @@ public readonly struct BigFraction public bool IsOne => Numerator == Denominator; + #region Constructors // CONSTRUCTORS // Fractional constructor @@ -151,7 +151,9 @@ public BigFraction(int i) Numerator = new BigInteger(i); Denominator = BigInteger.One; } + #endregion + #region Operators // OPERATORS // BigInteger to BigFraction @@ -196,22 +198,6 @@ public BigFraction(int i) /// Fraction to negate public static BigFraction operator -(BigFraction value) => new BigFraction(-value.Numerator, value.Denominator); - /* - // Operator % - /// - /// Modulus operator - /// - /// - /// - public static BigFraction operator %(BigFraction r, BigInteger mod) - { - var modmulden = r.Denominator * mod; - var remainder = r.Numerator % modmulden; - var answer = new BigFraction(remainder, r.Denominator); - return answer; - }*/ - - // Operator > /// /// Operator "greater than" /// @@ -221,7 +207,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator * r2.Denominator; var r2compare = r2.Numerator * r1.Denominator; - return r1compare.CompareTo(r2compare) == 1; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == r2.Denominator.Sign ? res > 0 : res < 0; } /// @@ -233,7 +220,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator; var r2compare = r2 * r1.Denominator; - return r1compare.CompareTo(r2compare) == 1; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == 1 ? res > 0 : res < 0; } /// @@ -245,7 +233,8 @@ public BigFraction(int i) { var r1compare = r1 * r2.Denominator; var r2compare = r2.Numerator; - return r1compare.CompareTo(r2compare) == 1; + var res = r1compare.CompareTo(r2compare); + return r2.Denominator.Sign == 1 ? res > 0 : res < 0; } // Operator < @@ -258,7 +247,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator * r2.Denominator; var r2compare = r2.Numerator * r1.Denominator; - return r1compare.CompareTo(r2compare) == -1; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == r2.Denominator.Sign ? res < 0 : res > 0; } /// @@ -270,7 +260,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator; var r2compare = r2 * r1.Denominator; - return r1compare.CompareTo(r2compare) == -1; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == 1 ? res < 0 : res > 0; } /// @@ -282,7 +273,8 @@ public BigFraction(int i) { var r1compare = r1 * r2.Denominator; var r2compare = r2.Numerator; - return r1compare.CompareTo(r2compare) == -1; + var res = r1compare.CompareTo(r2compare); + return r2.Denominator.Sign == 1 ? res < 0 : res > 0; } // Operator == @@ -369,7 +361,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator * r2.Denominator; var r2compare = r2.Numerator * r1.Denominator; - return r1compare.CompareTo(r2compare) == -1 || r1compare.CompareTo(r2compare) == 0; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == r2.Denominator.Sign ? res <= 0 : res >= 0; } /// @@ -381,7 +374,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator; var r2compare = r2 * r1.Denominator; - return r1compare.CompareTo(r2compare) == -1 || r1compare.CompareTo(r2compare) == 0; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == 1 ? res <= 0 : res >= 0; } /// @@ -393,7 +387,8 @@ public BigFraction(int i) { var r1compare = r1 * r2.Denominator; var r2compare = r2.Numerator; - return r1compare.CompareTo(r2compare) == -1 || r1compare.CompareTo(r2compare) == 0; + var res = r1compare.CompareTo(r2compare); + return r2.Denominator.Sign == 1 ? res <= 0 : res >= 0; } // Operator >= @@ -406,7 +401,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator * r2.Denominator; var r2compare = r2.Numerator * r1.Denominator; - return r1compare.CompareTo(r2compare) == 1 || r1compare.CompareTo(r2compare) == 0; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == r2.Denominator.Sign ? res >= 0 : res <= 0; } /// @@ -418,7 +414,8 @@ public BigFraction(int i) { var r1compare = r1.Numerator; var r2compare = r2 * r1.Denominator; - return r1compare.CompareTo(r2compare) == 1 || r1compare.CompareTo(r2compare) == 0; + var res = r1compare.CompareTo(r2compare); + return r1.Denominator.Sign == 1 ? res >= 0 : res <= 0; } /// @@ -430,7 +427,8 @@ public BigFraction(int i) { var r1compare = r1 * r2.Denominator; var r2compare = r2.Numerator; - return r1compare.CompareTo(r2compare) == 1 || r1compare.CompareTo(r2compare) == 0; + var res = r1compare.CompareTo(r2compare); + return r2.Denominator.Sign == 1 ? res >= 0 : res <= 0; } // Operator - @@ -532,6 +530,7 @@ public BigFraction(int i) /// First operand /// Second operand public static BigFraction operator /(BigInteger a, BigFraction b) => new BigFraction(a * b.Denominator, b.Numerator); + #endregion // Override Equals /// @@ -689,5 +688,7 @@ public static BigFraction FromDouble(double value, double accuracy) } } } + + public static BigFraction Abs(BigFraction value) => value < 0 ? -value : value; } } diff --git a/test/BigFractionTest/BigFractionTest.cs b/test/BigFractionTest/BigFractionTest.cs index f4e7a8c..5dd263d 100644 --- a/test/BigFractionTest/BigFractionTest.cs +++ b/test/BigFractionTest/BigFractionTest.cs @@ -186,15 +186,6 @@ public void Division() Assert.Equal(expected, a / b); } - /*[Fact(DisplayName = "%")] - public void Modulus() - { - BigFraction a = new BigFraction(5.25); - BigInteger b = new BigInteger(5); - BigFraction expected = new BigFraction(0.25); - Assert.Equal(expected, a % b); - }*/ - [Fact(DisplayName = ">")] public void Greater() { @@ -206,6 +197,36 @@ public void Greater() Assert.True(b > -a); Assert.False(-a > b); Assert.False(-a > -b); + Assert.False(a > a); + Assert.False(b > b); + + Assert.True(BigFraction.One > BigFraction.Zero); + Assert.True(BigFraction.One > BigFraction.MinusOne); + Assert.True(BigFraction.Zero > BigFraction.MinusOne); + + Assert.False(BigFraction.One > BigFraction.One); + Assert.False(BigFraction.Zero > BigFraction.Zero); + Assert.False(BigFraction.MinusOne > BigFraction.MinusOne); + + Assert.False(BigFraction.MinusOne > BigFraction.Zero); + Assert.False(BigFraction.Zero > BigFraction.One); + Assert.False(BigFraction.MinusOne > BigFraction.One); + + Assert.True(BigFraction.Zero > new BigFraction(1, -1)); + Assert.True(BigFraction.One > new BigFraction(1, -1)); + Assert.False(BigFraction.MinusOne > new BigFraction(1, -1)); + + Assert.True(BigInteger.Zero > new BigFraction(1, -1)); + Assert.True(BigInteger.One > new BigFraction(1, -1)); + Assert.False(BigInteger.MinusOne > new BigFraction(1, -1)); + + Assert.True(new BigFraction(1, -1) > new BigFraction(-2)); + Assert.False(new BigFraction(1,-1) > BigFraction.MinusOne); + Assert.False(new BigFraction(1, -1) > BigFraction.Zero); + + Assert.True(new BigFraction(1, -1) > new BigInteger(-2)); + Assert.False(new BigFraction(1,-1) > BigInteger.MinusOne); + Assert.False(new BigFraction(1, -1) > BigInteger.Zero); } [Fact(DisplayName = "<")] @@ -214,6 +235,41 @@ public void Smaller() BigFraction a = new BigFraction(-251.15); BigFraction b = new BigFraction(4.20); Assert.True(a < b); + Assert.False(b < a); + Assert.True(a < -b); + Assert.True(b < -a); + Assert.False(-a < b); + Assert.False(-a < -b); + Assert.False(a < a); + Assert.False(b < b); + + Assert.True(BigFraction.MinusOne < BigFraction.Zero); + Assert.True(BigFraction.MinusOne < BigFraction.One); + Assert.True(BigFraction.Zero < BigFraction.One); + + Assert.False(BigFraction.MinusOne < BigFraction.MinusOne); + Assert.False(BigFraction.Zero < BigFraction.Zero); + Assert.False(BigFraction.One < BigFraction.One); + + Assert.False(BigFraction.One < BigFraction.Zero); + Assert.False(BigFraction.Zero < BigFraction.MinusOne); + Assert.False(BigFraction.One < BigFraction.MinusOne); + + Assert.True(new BigFraction(-2) < new BigFraction(1, -1)); + Assert.False(BigFraction.Zero < new BigFraction(1, -1)); + Assert.False(BigFraction.MinusOne < new BigFraction(1, -1)); + + Assert.True(new BigInteger(-2) < new BigFraction(1, -1)); + Assert.False(BigInteger.MinusOne < new BigFraction(1, -1)); + Assert.False(BigInteger.Zero < new BigFraction(1, -1)); + + Assert.True(new BigFraction(1, -1) < BigFraction.One); + Assert.True(new BigFraction(1, -1) < BigFraction.Zero); + Assert.False(new BigFraction(1, -1) < BigFraction.MinusOne); + + Assert.True(new BigFraction(1, -1) < BigInteger.One); + Assert.True(new BigFraction(1, -1) < BigInteger.Zero); + Assert.False(new BigFraction(1, -1) < BigInteger.MinusOne); } [Fact(DisplayName = ">=")] @@ -540,6 +596,20 @@ public void doubletofraction() BigFraction expected = new BigFraction(new BigInteger(1), new BigInteger(2)); Assert.Equal(expected, b); } + + [Fact(DisplayName = "Abs")] + public void AbsTest() + { + Assert.Equal(BigFraction.One, BigFraction.Abs(new BigFraction(1))); + Assert.Equal(BigFraction.One, BigFraction.Abs(new BigFraction(-1))); + Assert.Equal(BigFraction.One, BigFraction.Abs(new BigFraction(1, -1))); + Assert.Equal(BigFraction.One, BigFraction.Abs(new BigFraction(-1, -1))); + Assert.Equal(BigFraction.One, BigFraction.Abs(new BigFraction(-1, 1))); + Assert.Equal(BigFraction.One, BigFraction.Abs(new BigFraction(1, 1))); + Assert.Equal(BigFraction.Zero, BigFraction.Abs(new BigFraction(0))); + Assert.Equal(BigFraction.Zero, BigFraction.Abs(new BigFraction(0, -1))); + Assert.Equal(BigFraction.Zero, BigFraction.Abs(new BigFraction(0, 1))); + } } }