Skip to content

Commit 6618818

Browse files
Standardize float and double constants further (#136)
* Add float and double constants for Integer/Long MAX/MIN_VALUE * Standardize float/double toString further The smallest possible float/double is now calculated including rounding and truncating This resolves decompiling differences by running with J17 vs J19 by becoming more in line with J19 Fixes #130
1 parent 11d406b commit 6618818

13 files changed

Lines changed: 198 additions & 70 deletions

FernFlower-Patches/0004-Fix-output-discrepancies-to-produce-stable-output.patch

Lines changed: 109 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,28 @@ index 75d4d0937f1e39fe630b1318a4ad531de7fbd644..d0ae9a7c3b20de44cb202390cc0dfd4d
9191
if (content != null) {
9292
out.write(content.getBytes(StandardCharsets.UTF_8));
9393
}
94+
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
95+
index 5448e7900953da79b2bc01f99fd7e8f3080148e7..b509376a6dbc3780f7c14c631bf51b7fc24aa50d 100644
96+
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
97+
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
98+
@@ -35,6 +35,8 @@ public interface IFernflowerPreferences {
99+
String IGNORE_INVALID_BYTECODE = "iib";
100+
String VERIFY_ANONYMOUS_CLASSES = "vac";
101+
102+
+ String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn";
103+
+
104+
String LOG_LEVEL = "log";
105+
String MAX_PROCESSING_METHOD = "mpm";
106+
String RENAME_ENTITIES = "ren";
107+
@@ -81,6 +83,8 @@ public interface IFernflowerPreferences {
108+
defaults.put(IGNORE_INVALID_BYTECODE, "0");
109+
defaults.put(VERIFY_ANONYMOUS_CLASSES, "0");
110+
111+
+ defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1");
112+
+
113+
defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name());
114+
defaults.put(MAX_PROCESSING_METHOD, "0");
115+
defaults.put(RENAME_ENTITIES, "0");
94116
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java b/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java
95117
index fad1ddcfb9d2e43720b4cd3acaa165ba86e94892..cf03900654e427bd435ba6dc2d5a0cec8c8708e4 100644
96118
--- a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java
@@ -332,15 +354,15 @@ index 82ae0a25a20d2727f611d359e699d6666d1e0ae4..a86f0d2887c6c19cb1d911ec43830eb6
332354

333355
return res;
334356
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
335-
index caa160fdc4ff5954b0976b11d81177278ae79ab6..e6363319573d157f5878dfdd93f8e60b44facb64 100644
357+
index caa160fdc4ff5954b0976b11d81177278ae79ab6..39df4ddd7afa01bba116063323630e514679a01f 100644
336358
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
337359
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
338360
@@ -216,7 +216,7 @@ public class ConstExprent extends Exprent {
339361
else if (floatVal == Float.NEGATIVE_INFINITY) {
340362
yield new TextBuffer("-1.0F / 0.0F");
341363
}
342364
- yield new TextBuffer(value.toString()).append('F');
343-
+ yield new TextBuffer(trimZeros(value.toString())).append('F');
365+
+ yield new TextBuffer(trimFloat(Float.toString(floatVal), floatVal)).append('F');
344366
}
345367
case CodeConstants.TYPE_DOUBLE -> {
346368
double doubleVal = (Double)value;
@@ -360,24 +382,98 @@ index caa160fdc4ff5954b0976b11d81177278ae79ab6..e6363319573d157f5878dfdd93f8e60b
360382
+ yield new TextBuffer("-1.0D / 0.0D");
361383
}
362384
- yield new TextBuffer(value.toString());
363-
+ yield new TextBuffer(trimZeros(value.toString())).append('D');
385+
+ yield new TextBuffer(trimDouble(Double.toString(doubleVal), doubleVal)).append('D');
364386
}
365387
case CodeConstants.TYPE_NULL -> new TextBuffer("null");
366388
case CodeConstants.TYPE_OBJECT -> {
367-
@@ -273,6 +273,18 @@ public class ConstExprent extends Exprent {
389+
@@ -273,6 +273,92 @@ public class ConstExprent extends Exprent {
368390
};
369391
}
370392

371-
+ // Different JVM implementations/version display Floats and Doubles with different number of trailing zeros.
372-
+ // This trims them all down to only the necessary amount.
373-
+ private static String trimZeros(String value) {
374-
+ int i = value.length() - 1;
375-
+ while (i >= 0 && value.charAt(i) == '0') {
376-
+ i--;
393+
+ // Different JVM implementations/version display Floats and Doubles with different String representations
394+
+ // for the same thing. This trims them all down to only the necessary amount.
395+
+ private static String trimFloat(String value, float start) {
396+
+ // Includes NaN and simple numbers
397+
+ if (value.length() <= 3 || !DecompilerContext.getOption(IFernflowerPreferences.STANDARDIZE_FLOATING_POINT_NUMBERS))
398+
+ return value;
399+
+
400+
+ String exp = "";
401+
+ int eIdx = value.indexOf('E');
402+
+ if (eIdx != -1) {
403+
+ exp = value.substring(eIdx);
404+
+ value = value.substring(0, eIdx);
405+
+ }
406+
+
407+
+ // Cut off digits that don't affect the value
408+
+ String temp = value;
409+
+ int dotIdx = value.indexOf('.');
410+
+ do {
411+
+ value = temp;
412+
+ temp = value.substring(0, value.length() - 1);
413+
+ } while (!temp.isEmpty() && !"-".equals(temp) && Float.parseFloat(temp + exp) == start);
414+
+
415+
+ if (dotIdx != -1 && value.indexOf('.') == -1) {
416+
+ value += ".0";
417+
+ } else if (dotIdx != -1) {
418+
+ String integer = value.substring(0, dotIdx);
419+
+ String decimal = value.substring(dotIdx + 1);
420+
+
421+
+ String rounded = (Integer.parseInt(integer) + 1) + ".0" + exp;
422+
+ if (Float.parseFloat(rounded) == start)
423+
+ return rounded;
424+
+
425+
+ long decimalVal = 1;
426+
+ for (int i = 0; i < decimal.length() - 1; i++) {
427+
+ decimalVal = (decimalVal - 1) * 10 + decimal.charAt(i) - '0' + 1;
428+
+ rounded = integer + '.' + decimalVal + exp;
429+
+ if (Float.parseFloat(rounded) == start)
430+
+ return rounded;
377431
+ }
378-
+ if (value.charAt(i) == '.')
379-
+ i++;
380-
+ return value.substring(0, i + 1);
432+
+ }
433+
+
434+
+ return value + exp;
435+
+ }
436+
+
437+
+ private static String trimDouble(String value, double start) {
438+
+ // Includes NaN and simple numbers
439+
+ if (value.length() <= 3 || !DecompilerContext.getOption(IFernflowerPreferences.STANDARDIZE_FLOATING_POINT_NUMBERS))
440+
+ return value;
441+
+
442+
+ String exp = "";
443+
+ int eIdx = value.indexOf('E');
444+
+ if (eIdx != -1) {
445+
+ exp = value.substring(eIdx);
446+
+ value = value.substring(0, eIdx);
447+
+ }
448+
+
449+
+ // Cut off digits that don't affect the value
450+
+ String temp = value;
451+
+ int dotIdx = value.indexOf('.');
452+
+ do {
453+
+ value = temp;
454+
+ temp = value.substring(0, value.length() - 1);
455+
+ } while (!temp.isEmpty() && !"-".equals(temp) && Double.parseDouble(temp + exp) == start);
456+
+
457+
+ if (dotIdx != -1 && value.indexOf('.') == -1) {
458+
+ value += ".0";
459+
+ } else if (dotIdx != -1) {
460+
+ String integer = value.substring(0, dotIdx);
461+
+ String decimal = value.substring(dotIdx + 1);
462+
+
463+
+ String rounded = (Long.parseLong(integer) + 1) + ".0" + exp;
464+
+ if (Double.parseDouble(rounded) == start)
465+
+ return rounded;
466+
+
467+
+ long decimalVal = 1;
468+
+ for (int i = 0; i < decimal.length() - 1; i++) {
469+
+ decimalVal = (decimalVal - 1) * 10 + decimal.charAt(i) - '0' + 1;
470+
+ rounded = integer + '.' + decimalVal + exp;
471+
+ if (Double.parseDouble(rounded) == start)
472+
+ return rounded;
473+
+ }
474+
+ }
475+
+
476+
+ return value + exp;
381477
+ }
382478
+
383479
private boolean inConstantVariable(String classSignature, String variableName) {

FernFlower-Patches/0005-Convert-Exprent.bytecode-to-a-BitMap.patch

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ index 13faa7fd16307e584d00bdf9f990e7cc7245babd..6cc60fd5314369cef21bd56c12e2af8e
480480
// getter and setter methods
481481
// *****************************************************************************
482482
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
483-
index e6363319573d157f5878dfdd93f8e60b44facb64..29cb0533a353084f83e19b565db6c0e66ab418c1 100644
483+
index 39df4ddd7afa01bba116063323630e514679a01f..56745ac71bbff7cbf8353579cd09f7482206677f 100644
484484
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
485485
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
486486
@@ -52,20 +52,20 @@ public class ConstExprent extends Exprent {
@@ -508,7 +508,7 @@ index e6363319573d157f5878dfdd93f8e60b44facb64..29cb0533a353084f83e19b565db6c0e6
508508
super(EXPRENT_CONST);
509509
this.constType = constType;
510510
this.value = value;
511-
@@ -423,6 +423,11 @@ public class ConstExprent extends Exprent {
511+
@@ -497,6 +497,11 @@ public class ConstExprent extends Exprent {
512512
return boolPermitted;
513513
}
514514

FernFlower-Patches/0009-Rework-of-Generics-system-for-better-output.patch

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -367,27 +367,25 @@ index 692c1b622ef7e065c9c970cf0a5289f9ca8869f5..f8c413c7b7302b201a739310677d0103
367367

368368
private static IIdentifierRenamer loadHelper(String className, IFernflowerLogger logger) {
369369
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
370-
index 5448e7900953da79b2bc01f99fd7e8f3080148e7..bdd34f0382b06687ef7fb3237bbc96ac322bdd5c 100644
370+
index b509376a6dbc3780f7c14c631bf51b7fc24aa50d..79108dd8772dc9444d66e6ba0cdd7f56ca382fbd 100644
371371
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
372372
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
373-
@@ -35,6 +35,8 @@ public interface IFernflowerPreferences {
374-
String IGNORE_INVALID_BYTECODE = "iib";
373+
@@ -36,6 +36,7 @@ public interface IFernflowerPreferences {
375374
String VERIFY_ANONYMOUS_CLASSES = "vac";
376375

376+
String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn";
377377
+ String INCLUDE_ENTIRE_CLASSPATH = "iec";
378-
+
378+
379379
String LOG_LEVEL = "log";
380380
String MAX_PROCESSING_METHOD = "mpm";
381-
String RENAME_ENTITIES = "ren";
382-
@@ -81,6 +83,8 @@ public interface IFernflowerPreferences {
383-
defaults.put(IGNORE_INVALID_BYTECODE, "0");
381+
@@ -84,6 +85,7 @@ public interface IFernflowerPreferences {
384382
defaults.put(VERIFY_ANONYMOUS_CLASSES, "0");
385383

384+
defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1");
386385
+ defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0");
387-
+
386+
388387
defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name());
389388
defaults.put(MAX_PROCESSING_METHOD, "0");
390-
defaults.put(RENAME_ENTITIES, "0");
391389
diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
392390
index 33906d3a433e4421bbf41c6aed5ff566a69a904a..c1126a2b7559e2f8a69a54ee0b7db2ceda3d9776 100644
393391
--- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java

FernFlower-Patches/0010-Improvements-to-var-and-var.patch

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,10 @@ index 81b4c480810a2f74388a4626a4dc0c2bfc523365..f0f66146eb4ecad4ed1bbd41712cace8
114114
}
115115
}
116116
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
117-
index 29cb0533a353084f83e19b565db6c0e66ab418c1..06025ab6d1c96e8bedb91b4efcbd2e00641c477e 100644
117+
index 56745ac71bbff7cbf8353579cd09f7482206677f..311fe8507fba664bd4b1e627f8ffbdb4c0c97cab 100644
118118
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
119119
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
120-
@@ -427,7 +427,12 @@ public class ConstExprent extends Exprent {
120+
@@ -501,7 +501,12 @@ public class ConstExprent extends Exprent {
121121
public void getBytecodeRange(BitSet values) {
122122
measureBytecode(values);
123123
}

FernFlower-Patches/0011-JAD-Style-variable-naming.patch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,10 @@ index 0000000000000000000000000000000000000000..872ec764f11131d384e59f08c4aac955
262262
+ }
263263
+}
264264
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
265-
index bdd34f0382b06687ef7fb3237bbc96ac322bdd5c..9641d4ea515d943009e87fe180a9e8a2569e8b14 100644
265+
index 79108dd8772dc9444d66e6ba0cdd7f56ca382fbd..3cbbb19b4dd705f67d0b2450996f704a9e293168 100644
266266
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
267267
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
268-
@@ -51,6 +51,9 @@ public interface IFernflowerPreferences {
268+
@@ -52,6 +52,9 @@ public interface IFernflowerPreferences {
269269
String LINE_SEPARATOR_WIN = "\r\n";
270270
String LINE_SEPARATOR_UNX = "\n";
271271

@@ -275,7 +275,7 @@ index bdd34f0382b06687ef7fb3237bbc96ac322bdd5c..9641d4ea515d943009e87fe180a9e8a2
275275
Map<String, Object> DEFAULTS = getDefaults();
276276

277277
static Map<String, Object> getDefaults() {
278-
@@ -93,7 +96,9 @@ public interface IFernflowerPreferences {
278+
@@ -95,7 +98,9 @@ public interface IFernflowerPreferences {
279279
defaults.put(BANNER, "");
280280
defaults.put(UNIT_TEST_MODE, "0");
281281
defaults.put(DUMP_ORIGINAL_LINES, "0");

FernFlower-Patches/0015-Add-new-command-line-argument-sef-SkipExtraFiles-To-.patch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ Subject: [PATCH] Add new command line argument -sef SkipExtraFiles: To skip
66

77

88
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
9-
index 9641d4ea515d943009e87fe180a9e8a2569e8b14..8337607e067c1c7cdc803058eab4bfb0ba3c9d3c 100644
9+
index 3cbbb19b4dd705f67d0b2450996f704a9e293168..f5fb8fc913c71b38ab0bffb5479d1f49725469ff 100644
1010
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
1111
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
12-
@@ -54,6 +54,8 @@ public interface IFernflowerPreferences {
12+
@@ -55,6 +55,8 @@ public interface IFernflowerPreferences {
1313
String USE_JAD_VARNAMING = "jvn"; // Overwrites any Local Variable names with JAD style names
1414
String USE_JAD_PARAMETER_RENAMING = "jpr"; // Include parameter names in JAD naming
1515

@@ -18,7 +18,7 @@ index 9641d4ea515d943009e87fe180a9e8a2569e8b14..8337607e067c1c7cdc803058eab4bfb0
1818
Map<String, Object> DEFAULTS = getDefaults();
1919

2020
static Map<String, Object> getDefaults() {
21-
@@ -98,6 +100,7 @@ public interface IFernflowerPreferences {
21+
@@ -100,6 +102,7 @@ public interface IFernflowerPreferences {
2222
defaults.put(DUMP_ORIGINAL_LINES, "0");
2323
defaults.put(USE_JAD_VARNAMING, "0");
2424
defaults.put(USE_JAD_PARAMETER_RENAMING, "0");

FernFlower-Patches/0022-Fix-shortname-imports-that-are-shadowed-by-super-cla.patch

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,20 +169,20 @@ index 6b7d72b6f599aaf04f122ff38ca872f469c9727e..cdd93212560a15372002c4d927a9debc
169169
+}
170170
\ No newline at end of file
171171
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
172-
index 8337607e067c1c7cdc803058eab4bfb0ba3c9d3c..ee6f1c77f2267fed499ee60a12ef319d8fc95e9f 100644
172+
index f5fb8fc913c71b38ab0bffb5479d1f49725469ff..53349248a038cea0ef82cdc2138ca93e722d1d06 100644
173173
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
174174
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
175-
@@ -36,6 +36,7 @@ public interface IFernflowerPreferences {
176-
String VERIFY_ANONYMOUS_CLASSES = "vac";
175+
@@ -37,6 +37,7 @@ public interface IFernflowerPreferences {
177176

177+
String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn";
178178
String INCLUDE_ENTIRE_CLASSPATH = "iec";
179179
+ String QUALIFY_INNER_CLASSES = "qin";
180180

181181
String LOG_LEVEL = "log";
182182
String MAX_PROCESSING_METHOD = "mpm";
183-
@@ -89,6 +90,7 @@ public interface IFernflowerPreferences {
184-
defaults.put(VERIFY_ANONYMOUS_CLASSES, "0");
183+
@@ -91,6 +92,7 @@ public interface IFernflowerPreferences {
185184

185+
defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1");
186186
defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0");
187187
+ defaults.put(QUALIFY_INNER_CLASSES, "1");
188188

0 commit comments

Comments
 (0)