Skip to content

Commit

Permalink
Hopefully address #83 and #81 on all computers
Browse files Browse the repository at this point in the history
v8.2 fixed #83 and #81 on my computer,
	but some people reported continued issues with many decimal numbers getting too-long representations
	(e.g., 11.11 would be represented as 11.109999999999999).
I have no idea if this commit will fix that issue for those people
	(because the issue was already fixed on my computer)
	but this is my first attempt to fix it since v8.2.
As noted in the changelog, this commit causes a very limited regression:
	some high-precision numbers like -6553693.3617752995 will now unnecessarily lose precision when reformatted,
	but we're still doing better than JSON-Viewer in that department, so I'm satisfied.
  • Loading branch information
molsonkiko committed Dec 13, 2024
1 parent fa4d9fb commit 43f105c
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 69 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

1. Use a different algorithm for representing decimal numbers to fix issues [83](https://github.com/molsonkiko/JsonToolsNppPlugin/issues/83) and [81](https://github.com/molsonkiko/JsonToolsNppPlugin/issues/81) on computers where v8.2 had not fixed those issues.
- As an unfortunate consequence of this fix, a *very very small percentage of very high-precision decimal numbers will lose precision* using this new algorithm. The vast majority of numbers with 17 digits of precision (the maximum precision attainable by JsonTools) will not lose precision when reformatted by JsonTools. For example, JsonTools will pretty-print `-6553693.3617752995` as the lower-precision `-6553693.3617753`. However, note that [JsonTools still handles high-precision doubles *better than the JSON-Viewer plugin*](https://github.com/NPP-JSONViewer/JSON-Viewer/issues/196).

### Fixed

1. When a file is [pretty-printed or compressed](/docs/README.md#the-basics) or [edited with RemesPath](/docs/RemesPath.md#editing-with-assignment-expressions), the caret will be scrolled into view. Previously, if the file contained very long lines and word wrapping was turned off, [the user might have to manually scroll to the left](https://github.com/molsonkiko/JsonToolsNppPlugin/issues/84) after pretty-printing or compressing.
Expand Down
15 changes: 2 additions & 13 deletions JsonToolsNppPlugin/JSONTools/JNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ public static void StrToSb(StringBuilder sb, string s)
/// <returns></returns>
public static string DoubleToString(double d)
{
string dubstring = d.ToString(DOT_DECIMAL_SEP);
string dubstring = d.ToString("R", DOT_DECIMAL_SEP);
int indexOfE = dubstring.IndexOf('E');
bool isValidLong = d == Math.Round(d) && !(d > long.MaxValue || d < long.MinValue);
if (isValidLong && indexOfE < 0)
Expand All @@ -424,18 +424,7 @@ public static string DoubleToString(double d)
// by turning something like 3.123E+15 into 3.123E+15.0 (a non-JSON number representation)
return dubstring + ".0";
}
// the default d.ToString(DOT_DECIMAL_SEP) might lose precision in some cases.
// We will nonetheless prefer this representation because the G17 representation
// has stupid unnecessarily verbose representations like representing 2317.24 as 2317.2399999999998
// We need to parse dubstring to make sure no precision has been lost.
try
{
if (double.Parse(dubstring) == d)
return dubstring; // default string representation has all necessary precision
}
catch { }
string d17 = d.ToString("G17", DOT_DECIMAL_SEP); // we need to use a string representation that retains as much precision as possible
return (isValidLong && d17.IndexOf('E') < 0) ? d17 + ".0" : d17;
return dubstring;
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions JsonToolsNppPlugin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("8.2.0.2")]
[assembly: AssemblyFileVersion("8.2.0.2")]
[assembly: AssemblyVersion("8.2.0.3")]
[assembly: AssemblyFileVersion("8.2.0.3")]
5 changes: 4 additions & 1 deletion JsonToolsNppPlugin/Tests/Benchmarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ public static bool BenchmarkAndFuzzParseAndFormatDoubles(int numTrials, int arra
string numArrayDumpedPreview = numArrayDumped.Length <= 200 ? numArrayDumped : numArrayDumped.Substring(0, 200) + "...";
if (badValues.Count > 0)
{
Npp.AddLine($"The following doubles did not round-trip:\r\n" + string.Join(", ", badValues.Select(x => x.ToString(JNode.DOT_DECIMAL_SEP))));
int valcount = badValues.Count;
int totValueCount = numTrials * arraySize;
string plural = valcount == 1 ? "" : "s";
Npp.AddLine($"FAIL: The following {valcount} double{plural} (out of {totValueCount} total) did not round-trip:\r\n" + string.Join(", ", badValues.Select(x => x.ToString(JNode.DOT_DECIMAL_SEP))));
return true;
}
Npp.AddLine($"Representative example of result of re-compression = \"{numArrayDumpedPreview}\"");
Expand Down
2 changes: 1 addition & 1 deletion JsonToolsNppPlugin/Tests/TestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public static async Task RunAll()
"JsonParser performance",
true, false
),
(() => Benchmarker.BenchmarkAndFuzzParseAndFormatDoubles(32, 5000),
(() => Benchmarker.BenchmarkAndFuzzParseAndFormatDoubles(40, 5500),
"performance and correctness of parsing and dumping arrays of non-integer numbers",
false, false),
//(() => Benchmarker.BenchmarkParsingAndLintingJsonWithErrors(30), "JsonParser performance and performance of JsonLint.message"),
Expand Down
Loading

0 comments on commit 43f105c

Please sign in to comment.