diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 8c7c08d9f..88b744885 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -307,6 +307,20 @@ powers of `x` found it.
|---|---|---|
| `"(3x - 4) * sqrt(x) + 3 + 3x - 4x^2 = 0".Solve("x")` | four roots, one of them 1.3233…, which is not a root | the other three |
+### A floor or a ceil of a complex argument near a real limit is not the step of the limit
+
+**Silent: a different answer.** The limit of a floor or a ceil read its argument as real along the path. `4^((-1)^x)`
+at 1 from the right tends to 1/4 from below the real line, where every floor is `-i`, and the limit was the floor of 1/4,
+`0`. An argument that is complex just off the destination now has its imaginary part's side asked, and where that is
+not decided the limit is left unevaluated. Here it is not decided, so the side whose answer was right, the left, is left
+unevaluated too. An argument real near the destination is read as before.
+
+| Input | Was (2.6.0) | Now |
+|---|---|---|
+| `limitright(floor(4^((-1)^x)), x, 1)` | `0` | unevaluated |
+| `limitleft(ceil(4^((-1)^x)), x, 1)` | `1` | unevaluated |
+| `limitleft(floor(4^((-1)^x)), x, 1)` | `0` | unevaluated |
+
### A step function that has a limit from one side is that limit on that side
**Silent: a limit of a power whose base is a `floor`, `ceil`, `round` or `sgn` that is 0 on the side approached is 0,
diff --git a/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Classes.cs b/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Classes.cs
index a3ea02ba4..dbce3eb2c 100644
--- a/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Classes.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Classes.cs
@@ -498,20 +498,66 @@ partial record Absf
// genuinely complex limit has an imaginary part that can arrive at an integer from
// one side or the other.
//
- // Like the Absf and Signumf overrides above, this reads the argument as real-valued
- // along the path. An argument that is complex near the destination and real at it
- // can still be answered here when it should not be; that is the assumption those
- // two already make, and narrowing it wants a way to decide realness that this
- // library does not have yet -- https://github.com/asc-community/AngouriMath/issues/721.
+ // The Absf and Signumf overrides above read the argument as real-valued along the path.
+ // This one asks: an argument that is complex near the destination and real at it is
+ // read below by the side its imaginary part arrives from.
if (value is not Complex { RealPart: var real, ImaginaryPart: var imaginary })
return null;
+ // A real limit of an argument that is not real near the destination has an imaginary
+ // part tending to 0, which is a jump of its own: floor(4^((-1)^x)) at 1 from the right
+ // tends to 1/4 from below the real line, where every value's floor is -i, and the
+ // floor of the limit, 0, was the answer. Where the argument is real near the
+ // destination -- every argument this read as real before, sqrt(x) at 4 among them --
+ // nothing is added; where it is not, the side the imaginary part arrives from decides
+ // the step, and where that is not decided the limit is declined.
+ Entity imaginaryStep = Integer.Zero;
+ if (value is Real)
+ {
+ if (ImaginaryStep() is not { } step)
+ return null;
+ imaginaryStep = step;
+ }
+ Entity WithTheImaginaryStep(Entity realAnswer)
+ => imaginaryStep is Integer { IsZero: true } ? realAnswer : realAnswer + imaginaryStep * MathS.i;
if (SitsOnAJump(real))
return value is Integer jump && SignNear(argument - jump, x, dist, side) is { } arrivesFrom
- ? atAJump(jump, arrivesFrom)
+ ? WithTheImaginaryStep(atAJump(jump, arrivesFrom))
: null;
if (value is not Real && SitsOnAJump(imaginary))
return null;
- return rebuild(limit);
+ return WithTheImaginaryStep(rebuild(limit));
+
+ // Real near the destination where it is real at a point just off it on each side
+ // approached: realness is not decided for every shape -- x^x is outside what
+ // TreeAnalyzer lists -- and a sample only ever sends the limit to the question of the
+ // imaginary part's side, or to declining, never to an answer of its own.
+ Entity? ImaginaryStep()
+ {
+ if (Functions.TreeAnalyzer.IsRealValued(argument, x) || IsRealJustOff())
+ return Integer.Zero;
+ return SignNear(MathS.Im(argument), x, dist, side) is { } arrivesFrom && arrivesFrom != 0
+ ? atAJump(Integer.Zero, arrivesFrom)
+ : null;
+ }
+
+ bool IsRealJustOff()
+ {
+ var offsets = side switch
+ {
+ ApproachFrom.Left => new[] { -1 },
+ ApproachFrom.Right => new[] { 1 },
+ _ => new[] { -1, 1 },
+ };
+ foreach (var offset in offsets)
+ {
+ Entity at = dist == Real.PositiveInfinity ? Integer.Create(1000000)
+ : dist == Real.NegativeInfinity ? Integer.Create(-1000000)
+ : dist + Rational.Create(offset, 1000000);
+ if (argument.Substitute(x, at).Evaled is not Real)
+ return false;
+ }
+ return true;
+ }
static bool SitsOnAJump(Real part) =>
part is Integer || part.EDecimal.CompareTo(part.EDecimal.Floor()) == 0;
diff --git a/Sources/Tests/UnitTests/Calculus/AStepOfAComplexArgumentNearARealLimitTest.cs b/Sources/Tests/UnitTests/Calculus/AStepOfAComplexArgumentNearARealLimitTest.cs
new file mode 100644
index 000000000..c7a55f748
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/AStepOfAComplexArgumentNearARealLimitTest.cs
@@ -0,0 +1,41 @@
+//
+// Copyright (c) 2019-2026 Angouri.
+// AngouriMath is licensed under MIT.
+// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
+// Website: https://am.angouri.org.
+//
+
+using AngouriMath.Core;
+using Xunit;
+using static AngouriMath.Entity;
+
+namespace AngouriMath.Tests.Calculus
+{
+ ///
+ /// The limit of a floor or a ceil read its argument as real along the path. 4^((-1)^x) at 1 from the right
+ /// tends to 1/4 from below the real line, so that every floor near it is -i, and the limit was the floor of
+ /// 1/4, 0. An argument that is complex just off the destination now has its imaginary part's side asked, and where
+ /// that is not decided the limit is declined. An argument real there is read as before. Found by limitcheck at
+ /// DEPTH=3; no issue was filed.
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class AStepOfAComplexArgumentNearARealLimitTest
+ {
+ [Theory]
+ [InlineData("floor(4^((-1)^x))", "1", ApproachFrom.Right)]
+ [InlineData("floor(4^((-1)^x))", "-1", ApproachFrom.Right)]
+ [InlineData("ceil(4^((-1)^x))", "1", ApproachFrom.Left)]
+ public void IsNotTheStepOfTheLimit(string input, string destination, ApproachFrom side)
+ => Assert.IsType(MathS.FromString(input).Limit("x", destination, side));
+
+ [Theory]
+ [InlineData("floor(sqrt(x))", "4", ApproachFrom.Left, "1")]
+ [InlineData("floor(sqrt(x))", "4", ApproachFrom.Right, "2")]
+ [InlineData("floor(x^x)", "2", ApproachFrom.Left, "3")]
+ [InlineData("floor(x^x)", "1", ApproachFrom.Left, "0")]
+ [InlineData("floor(ln(x))", "1", ApproachFrom.Left, "-1")]
+ [InlineData("ceil(x^(1/3))", "1", ApproachFrom.Right, "2")]
+ public void ARealArgumentIsReadAsBefore(string input, string destination, ApproachFrom side, string expected)
+ => Assert.Equal(MathS.FromString(expected), MathS.FromString(input).Limit("x", destination, side));
+ }
+}