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
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static string RenderNum(Real number)
return RealPart.Latexize();
else if (RealPart is Integer(0))
return RenderNum(ImaginaryPart) + @"\mathrm{i}"; // Display i upright per ISO 80000-2.
var (im, sign) = ImaginaryPart > 0 ? (ImaginaryPart, "+") : (-ImaginaryPart, "-");
var (im, sign) = ImaginaryPart > 0 ? (ImaginaryPart, "+") : (NegatedAsItIs(ImaginaryPart), "-");
return RealPart.Latexize() + " " + sign + " " +
(im == 1 ? "" : im.Latexize(ImaginaryPart is Rational and not Integer)) + @"\mathrm{i}";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,23 @@ static string RenderNum(Real number)
return RealPart.Stringize();
else if (RealPart is Integer(0))
return RenderNum(ImaginaryPart) + times + "i";
var (im, sign) = ImaginaryPart > 0 ? (ImaginaryPart, "+") : (-ImaginaryPart, "-");
var (im, sign) = ImaginaryPart > 0 ? (ImaginaryPart, "+") : (NegatedAsItIs(ImaginaryPart), "-");
return RealPart.Stringize() + " " + sign + " " + RenderNum(im) + times + "i";
}

/// <summary>
/// <paramref name="number"/> negated, and nothing else. Negating makes a new number,
/// which is downcast under the setting in force when it is made, and a number made
/// with downcasting off could come back different: <c>0.333...</c> to forty digits
/// as the rational 1/3, printed without the product sign a fraction needs, so that
/// <c>1 - 0.333...i</c> read back as <c>1 + i/3</c>; and <c>9.5e-114</c> as 0.
/// https://github.com/asc-community/AngouriMath/issues/1610
/// </summary>
internal static Real NegatedAsItIs(Real number)
{
using var _ = MathS.Settings.DowncastingEnabled.Set(false);
return -number;
}
/// <inheritdoc/>
public override string ToString() => Stringize();
}
Expand Down
29 changes: 29 additions & 0 deletions Sources/Tests/UnitTests/Convenience/StringizeRoundTripTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,5 +387,34 @@ public void AWordContainingTheTokenIsStillAVariable(string source) =>
[InlineData("integral(domain(x, ZZ), x)")]
[InlineData("{ domain(x, ZZ) : x > 0 }")]
public void ANarrowedCodomainRoundTrips(string source) => AssertRoundTrip(source);

/// <summary>
/// A number prints as it is, whatever the downcasting setting when it is printed. A
/// negative imaginary part was negated to be printed, which made a new number under the
/// setting in force, so a number made with downcasting off printed as another one once it
/// was back on: <c>1 - 0.333...i</c> as <c>1 - 1/3i</c>, which reads back as <c>1 + i/3</c>,
/// and the imaginary part of <c>erfc(16 - 0.5i)</c> as 0.
/// <a href="https://github.com/asc-community/AngouriMath/issues/1610">#1610</a>
/// </summary>
[Theory]
[InlineData("1", "-0.3333333333333333333333333333333333333333")]
[InlineData("2", "-0.5000000000000000000000000000001")]
[InlineData("-2.8337075375928474951E-113", "-9.4899608506981397569E-114")]
public void ANumberMadeWithoutDowncastingPrintsAsItIs(string real, string imaginary)
{
Entity.Number.Complex number;
using (MathS.Settings.DowncastingEnabled.Set(false))
number = Entity.Number.Complex.Create(PeterO.Numbers.EDecimal.FromString(real), PeterO.Numbers.EDecimal.FromString(imaginary));
var printed = number.Stringize();
var latex = number.Latexize();
using (MathS.Settings.DowncastingEnabled.Set(false))
{
var read = MathS.FromString(printed, useCache: false).EvalNumerical();
Assert.True(read.RealPart.EDecimal.CompareTo(number.RealPart.EDecimal) == 0
&& read.ImaginaryPart.EDecimal.CompareTo(number.ImaginaryPart.EDecimal) == 0,
$"{printed} reads back as {read}");
}
Assert.Contains(PeterO.Numbers.EDecimal.FromString(imaginary).Negate() + @"\mathrm{i}", latex);
}
}
}
Loading