Skip to content

Commit

Permalink
Standardize float and double constants further (#136)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
SizableShrimp authored Mar 4, 2023
1 parent 11d406b commit 6618818
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ index 75d4d0937f1e39fe630b1318a4ad531de7fbd644..d0ae9a7c3b20de44cb202390cc0dfd4d
if (content != null) {
out.write(content.getBytes(StandardCharsets.UTF_8));
}
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
index 5448e7900953da79b2bc01f99fd7e8f3080148e7..b509376a6dbc3780f7c14c631bf51b7fc24aa50d 100644
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
@@ -35,6 +35,8 @@ public interface IFernflowerPreferences {
String IGNORE_INVALID_BYTECODE = "iib";
String VERIFY_ANONYMOUS_CLASSES = "vac";

+ String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn";
+
String LOG_LEVEL = "log";
String MAX_PROCESSING_METHOD = "mpm";
String RENAME_ENTITIES = "ren";
@@ -81,6 +83,8 @@ public interface IFernflowerPreferences {
defaults.put(IGNORE_INVALID_BYTECODE, "0");
defaults.put(VERIFY_ANONYMOUS_CLASSES, "0");

+ defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1");
+
defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name());
defaults.put(MAX_PROCESSING_METHOD, "0");
defaults.put(RENAME_ENTITIES, "0");
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java b/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java
index fad1ddcfb9d2e43720b4cd3acaa165ba86e94892..cf03900654e427bd435ba6dc2d5a0cec8c8708e4 100644
--- a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java
Expand Down Expand Up @@ -332,15 +354,15 @@ index 82ae0a25a20d2727f611d359e699d6666d1e0ae4..a86f0d2887c6c19cb1d911ec43830eb6

return res;
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
index caa160fdc4ff5954b0976b11d81177278ae79ab6..e6363319573d157f5878dfdd93f8e60b44facb64 100644
index caa160fdc4ff5954b0976b11d81177278ae79ab6..39df4ddd7afa01bba116063323630e514679a01f 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
@@ -216,7 +216,7 @@ public class ConstExprent extends Exprent {
else if (floatVal == Float.NEGATIVE_INFINITY) {
yield new TextBuffer("-1.0F / 0.0F");
}
- yield new TextBuffer(value.toString()).append('F');
+ yield new TextBuffer(trimZeros(value.toString())).append('F');
+ yield new TextBuffer(trimFloat(Float.toString(floatVal), floatVal)).append('F');
}
case CodeConstants.TYPE_DOUBLE -> {
double doubleVal = (Double)value;
Expand All @@ -360,24 +382,98 @@ index caa160fdc4ff5954b0976b11d81177278ae79ab6..e6363319573d157f5878dfdd93f8e60b
+ yield new TextBuffer("-1.0D / 0.0D");
}
- yield new TextBuffer(value.toString());
+ yield new TextBuffer(trimZeros(value.toString())).append('D');
+ yield new TextBuffer(trimDouble(Double.toString(doubleVal), doubleVal)).append('D');
}
case CodeConstants.TYPE_NULL -> new TextBuffer("null");
case CodeConstants.TYPE_OBJECT -> {
@@ -273,6 +273,18 @@ public class ConstExprent extends Exprent {
@@ -273,6 +273,92 @@ public class ConstExprent extends Exprent {
};
}

+ // Different JVM implementations/version display Floats and Doubles with different number of trailing zeros.
+ // This trims them all down to only the necessary amount.
+ private static String trimZeros(String value) {
+ int i = value.length() - 1;
+ while (i >= 0 && value.charAt(i) == '0') {
+ i--;
+ // Different JVM implementations/version display Floats and Doubles with different String representations
+ // for the same thing. This trims them all down to only the necessary amount.
+ private static String trimFloat(String value, float start) {
+ // Includes NaN and simple numbers
+ if (value.length() <= 3 || !DecompilerContext.getOption(IFernflowerPreferences.STANDARDIZE_FLOATING_POINT_NUMBERS))
+ return value;
+
+ String exp = "";
+ int eIdx = value.indexOf('E');
+ if (eIdx != -1) {
+ exp = value.substring(eIdx);
+ value = value.substring(0, eIdx);
+ }
+
+ // Cut off digits that don't affect the value
+ String temp = value;
+ int dotIdx = value.indexOf('.');
+ do {
+ value = temp;
+ temp = value.substring(0, value.length() - 1);
+ } while (!temp.isEmpty() && !"-".equals(temp) && Float.parseFloat(temp + exp) == start);
+
+ if (dotIdx != -1 && value.indexOf('.') == -1) {
+ value += ".0";
+ } else if (dotIdx != -1) {
+ String integer = value.substring(0, dotIdx);
+ String decimal = value.substring(dotIdx + 1);
+
+ String rounded = (Integer.parseInt(integer) + 1) + ".0" + exp;
+ if (Float.parseFloat(rounded) == start)
+ return rounded;
+
+ long decimalVal = 1;
+ for (int i = 0; i < decimal.length() - 1; i++) {
+ decimalVal = (decimalVal - 1) * 10 + decimal.charAt(i) - '0' + 1;
+ rounded = integer + '.' + decimalVal + exp;
+ if (Float.parseFloat(rounded) == start)
+ return rounded;
+ }
+ if (value.charAt(i) == '.')
+ i++;
+ return value.substring(0, i + 1);
+ }
+
+ return value + exp;
+ }
+
+ private static String trimDouble(String value, double start) {
+ // Includes NaN and simple numbers
+ if (value.length() <= 3 || !DecompilerContext.getOption(IFernflowerPreferences.STANDARDIZE_FLOATING_POINT_NUMBERS))
+ return value;
+
+ String exp = "";
+ int eIdx = value.indexOf('E');
+ if (eIdx != -1) {
+ exp = value.substring(eIdx);
+ value = value.substring(0, eIdx);
+ }
+
+ // Cut off digits that don't affect the value
+ String temp = value;
+ int dotIdx = value.indexOf('.');
+ do {
+ value = temp;
+ temp = value.substring(0, value.length() - 1);
+ } while (!temp.isEmpty() && !"-".equals(temp) && Double.parseDouble(temp + exp) == start);
+
+ if (dotIdx != -1 && value.indexOf('.') == -1) {
+ value += ".0";
+ } else if (dotIdx != -1) {
+ String integer = value.substring(0, dotIdx);
+ String decimal = value.substring(dotIdx + 1);
+
+ String rounded = (Long.parseLong(integer) + 1) + ".0" + exp;
+ if (Double.parseDouble(rounded) == start)
+ return rounded;
+
+ long decimalVal = 1;
+ for (int i = 0; i < decimal.length() - 1; i++) {
+ decimalVal = (decimalVal - 1) * 10 + decimal.charAt(i) - '0' + 1;
+ rounded = integer + '.' + decimalVal + exp;
+ if (Double.parseDouble(rounded) == start)
+ return rounded;
+ }
+ }
+
+ return value + exp;
+ }
+
private boolean inConstantVariable(String classSignature, String variableName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ index 13faa7fd16307e584d00bdf9f990e7cc7245babd..6cc60fd5314369cef21bd56c12e2af8e
// getter and setter methods
// *****************************************************************************
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
index e6363319573d157f5878dfdd93f8e60b44facb64..29cb0533a353084f83e19b565db6c0e66ab418c1 100644
index 39df4ddd7afa01bba116063323630e514679a01f..56745ac71bbff7cbf8353579cd09f7482206677f 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
@@ -52,20 +52,20 @@ public class ConstExprent extends Exprent {
Expand Down Expand Up @@ -508,7 +508,7 @@ index e6363319573d157f5878dfdd93f8e60b44facb64..29cb0533a353084f83e19b565db6c0e6
super(EXPRENT_CONST);
this.constType = constType;
this.value = value;
@@ -423,6 +423,11 @@ public class ConstExprent extends Exprent {
@@ -497,6 +497,11 @@ public class ConstExprent extends Exprent {
return boolPermitted;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,27 +367,25 @@ index 692c1b622ef7e065c9c970cf0a5289f9ca8869f5..f8c413c7b7302b201a739310677d0103

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

String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn";
+ String INCLUDE_ENTIRE_CLASSPATH = "iec";
+
String LOG_LEVEL = "log";
String MAX_PROCESSING_METHOD = "mpm";
String RENAME_ENTITIES = "ren";
@@ -81,6 +83,8 @@ public interface IFernflowerPreferences {
defaults.put(IGNORE_INVALID_BYTECODE, "0");
@@ -84,6 +85,7 @@ public interface IFernflowerPreferences {
defaults.put(VERIFY_ANONYMOUS_CLASSES, "0");

defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1");
+ defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0");
+
defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name());
defaults.put(MAX_PROCESSING_METHOD, "0");
defaults.put(RENAME_ENTITIES, "0");
diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
index 33906d3a433e4421bbf41c6aed5ff566a69a904a..c1126a2b7559e2f8a69a54ee0b7db2ceda3d9776 100644
--- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
Expand Down
4 changes: 2 additions & 2 deletions FernFlower-Patches/0010-Improvements-to-var-and-var.patch
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ index 81b4c480810a2f74388a4626a4dc0c2bfc523365..f0f66146eb4ecad4ed1bbd41712cace8
}
}
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
index 29cb0533a353084f83e19b565db6c0e66ab418c1..06025ab6d1c96e8bedb91b4efcbd2e00641c477e 100644
index 56745ac71bbff7cbf8353579cd09f7482206677f..311fe8507fba664bd4b1e627f8ffbdb4c0c97cab 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
@@ -427,7 +427,12 @@ public class ConstExprent extends Exprent {
@@ -501,7 +501,12 @@ public class ConstExprent extends Exprent {
public void getBytecodeRange(BitSet values) {
measureBytecode(values);
}
Expand Down
6 changes: 3 additions & 3 deletions FernFlower-Patches/0011-JAD-Style-variable-naming.patch
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,10 @@ index 0000000000000000000000000000000000000000..872ec764f11131d384e59f08c4aac955
+ }
+}
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
index bdd34f0382b06687ef7fb3237bbc96ac322bdd5c..9641d4ea515d943009e87fe180a9e8a2569e8b14 100644
index 79108dd8772dc9444d66e6ba0cdd7f56ca382fbd..3cbbb19b4dd705f67d0b2450996f704a9e293168 100644
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
@@ -51,6 +51,9 @@ public interface IFernflowerPreferences {
@@ -52,6 +52,9 @@ public interface IFernflowerPreferences {
String LINE_SEPARATOR_WIN = "\r\n";
String LINE_SEPARATOR_UNX = "\n";

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

static Map<String, Object> getDefaults() {
@@ -93,7 +96,9 @@ public interface IFernflowerPreferences {
@@ -95,7 +98,9 @@ public interface IFernflowerPreferences {
defaults.put(BANNER, "");
defaults.put(UNIT_TEST_MODE, "0");
defaults.put(DUMP_ORIGINAL_LINES, "0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Subject: [PATCH] Add new command line argument -sef SkipExtraFiles: To skip


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

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

static Map<String, Object> getDefaults() {
@@ -98,6 +100,7 @@ public interface IFernflowerPreferences {
@@ -100,6 +102,7 @@ public interface IFernflowerPreferences {
defaults.put(DUMP_ORIGINAL_LINES, "0");
defaults.put(USE_JAD_VARNAMING, "0");
defaults.put(USE_JAD_PARAMETER_RENAMING, "0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,20 @@ index 6b7d72b6f599aaf04f122ff38ca872f469c9727e..cdd93212560a15372002c4d927a9debc
+}
\ No newline at end of file
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
index 8337607e067c1c7cdc803058eab4bfb0ba3c9d3c..ee6f1c77f2267fed499ee60a12ef319d8fc95e9f 100644
index f5fb8fc913c71b38ab0bffb5479d1f49725469ff..53349248a038cea0ef82cdc2138ca93e722d1d06 100644
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
@@ -36,6 +36,7 @@ public interface IFernflowerPreferences {
String VERIFY_ANONYMOUS_CLASSES = "vac";
@@ -37,6 +37,7 @@ public interface IFernflowerPreferences {

String STANDARDIZE_FLOATING_POINT_NUMBERS = "sfn";
String INCLUDE_ENTIRE_CLASSPATH = "iec";
+ String QUALIFY_INNER_CLASSES = "qin";

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

defaults.put(STANDARDIZE_FLOATING_POINT_NUMBERS, "1");
defaults.put(INCLUDE_ENTIRE_CLASSPATH, "0");
+ defaults.put(QUALIFY_INNER_CLASSES, "1");

Expand Down
Loading

0 comments on commit 6618818

Please sign in to comment.