Skip to content
Merged
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
13 changes: 13 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,19 @@ integrals with `0` ([#1769](https://github.com/asc-community/AngouriMath/issues/
| `"e^(-160)".ToEntity().InnerSimplified` | `0` | `e ^ (-160)` |
| `"x^n*((1 - d^2)/x - x)^3*(1 + x^2 - d*x)/(x - d)/pi^2".ToEntity().Simplify()` | `0 provided not x - d = 0 and ...` | `x ^ n * ((1 - d ^ 2) / x - x) ^ 3 * (1 - d * x + x ^ 2) / (pi ^ 2 * (x - d))` |

### The floor and the ceiling of a rational are exact whatever its size

**Wrong answers fixed.** The floor and the ceiling of an exact rational went through a decimal at the
working precision, and a rational with more digits than that was rounded onto the integer beside it
before it was rounded down or up: `floor(10^120 - 1/3)` came out `10^120`. They are taken from the
numerator and the denominator now, exactly
([#1807](https://github.com/asc-community/AngouriMath/issues/1807)).

| Input | Was (2.5.0) | Now |
|---|---|---|
| `"floor((3 * 10^120 - 1)/3)".ToEntity().InnerSimplified` | `10^120`, written out | `10^120 - 1` |
| `"ceil((3 * 10^120 + 1)/3)".ToEntity().InnerSimplified` | `10^120`, written out | `10^120 + 1` |

### A rational function with symbols in it beside a root of a linear is split into partial fractions first

**Answers where there were none.** `1/(x (1 + x^2) sqrt(a + b x))` was declined, while
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,11 @@ protected override Entity InnerSimplify(bool isExact)
// both, and the exception was reaching the caller:
// https://github.com/asc-community/AngouriMath/issues/830
Real { IsFinite: false } n => n,
Rational n => Integer.Create(n.EDecimal.Floor().ToEInteger()),
// From the numerator and the denominator: through EDecimal a rational of more
// digits than the precision was rounded onto the integer beside it, and
// floor(10^120 - 1/3) came out 10^120.
// https://github.com/asc-community/AngouriMath/issues/1807
Rational n => Integer.Create(RoundedQuotient(n.ERational, up: false)),
Real n when !isExact => Integer.Create(n.EDecimal.Floor().ToEInteger()),
Complex n when !isExact => Complex.Create(
n.RealPart.EDecimal.Floor(), n.ImaginaryPart.EDecimal.Floor()),
Expand All @@ -720,6 +724,21 @@ protected override Entity InnerSimplify(bool isExact)
(@this, a) => ((Floorf)@this).New(a), isExact);
}

/// <summary>
/// The floor, or with <paramref name="up"/> the ceiling, of a rational, exactly: the quotient of
/// its numerator by its denominator, which is positive, rounded toward zero by the division and
/// moved one step where that went the wrong way.
/// </summary>
private static PeterO.Numbers.EInteger RoundedQuotient(PeterO.Numbers.ERational value, bool up)
{
var division = value.Numerator.DivRem(value.Denominator);
var (quotient, remainder) = (division[0], division[1]);
if (remainder.IsZero)
return quotient;
return up ? (value.Numerator.Sign > 0 ? quotient + PeterO.Numbers.EInteger.One : quotient)
: (value.Numerator.Sign < 0 ? quotient - PeterO.Numbers.EInteger.One : quotient);
}

public partial record Ceilf
{
// Defined everywhere in the complex plane, taken componentwise.
Expand All @@ -733,7 +752,7 @@ protected override Entity InnerSimplify(bool isExact)
Integer n => n,
// As in Floorf: https://github.com/asc-community/AngouriMath/issues/830
Real { IsFinite: false } n => n,
Rational n => Integer.Create(n.EDecimal.Ceiling().ToEInteger()),
Rational n => Integer.Create(RoundedQuotient(n.ERational, up: true)),
Real n when !isExact => Integer.Create(n.EDecimal.Ceiling().ToEInteger()),
Complex n when !isExact => Complex.Create(
n.RealPart.EDecimal.Ceiling(), n.ImaginaryPart.EDecimal.Ceiling()),
Expand Down
21 changes: 21 additions & 0 deletions Sources/Tests/UnitTests/Convenience/FloorCeilTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,26 @@ public void TheLimitAwayFromAJumpIsTheValue(string input, string destination, st
public void TheLimitOnAJumpIsDeclined(string input, string destination)
=> Assert.IsType<Entity.Limitf>(
input.ToEntity().Limit("x", destination.ToEntity()));

/// <summary>
/// A rational with more digits than the precision, a third away from an integer on either
/// side, rounded exactly: through <c>EDecimal</c> it was rounded onto the integer first, and
/// <c>floor(10^120 - 1/3)</c> came out <c>10^120</c>.
/// <a href="https://github.com/asc-community/AngouriMath/issues/1807">#1807</a>
/// </summary>
[Theory]
[InlineData("floor((3 * 10^120 - 1)/3)", "10^120 - 1")]
[InlineData("floor((3 * 10^120 + 1)/3)", "10^120")]
[InlineData("ceil((3 * 10^120 - 1)/3)", "10^120")]
[InlineData("ceil((3 * 10^120 + 1)/3)", "10^120 + 1")]
[InlineData("floor(-(3 * 10^400 - 1)/3)", "-10^400")]
[InlineData("floor(-(3 * 10^400 + 1)/3)", "-10^400 - 1")]
[InlineData("ceil(-(3 * 10^400 - 1)/3)", "-10^400 + 1")]
[InlineData("ceil(-(3 * 10^400 + 1)/3)", "-10^400")]
public void ARationalOfManyDigitsIsRoundedExactly(string input, string expected)
{
Assert.Equal(expected.ToEntity().InnerSimplified, input.ToEntity().InnerSimplified);
Assert.Equal(expected.ToEntity().InnerSimplified, input.ToEntity().Evaled);
}
}
}
Loading