Browse Source

Apply suggestions from code review.

pull/1350/head
Siegfried Pammer 6 years ago
parent
commit
063c06c9c8
  1. 12
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.cs
  2. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.il
  3. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.opt.il
  4. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.opt.roslyn.il
  5. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.roslyn.il
  6. 95
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

12
ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.cs

@ -83,6 +83,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -83,6 +83,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public const float Float_LooksLikePI = 3.1415925f;
public const float Float_LooksLikePI2 = 3.14159f;
public const float Float_LooksLikePI3 = 3.141f;
public const float Float_BeforePI = 3.1415925f;
public const float Float_AfterPI = 3.141593f;
public const float Float_Negated_PI = -(float)Math.PI;
public const float Float_Negated_HalfOfPI = -(float)Math.PI / 2f;
public const float Float_Negated_QuarterOfPI = -(float)Math.PI / 4f;
@ -97,6 +99,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -97,6 +99,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public const float Float_Negated_PITimes90 = (float)Math.PI * -90f;
public const float Float_Negated_PITimes180 = (float)Math.PI * -180f;
public const float Float_Negated_LooksLikePI = -3.141f;
public const float Float_Negated_BeforePI = -3.1415925f;
public const float Float_Negated_AfterPI = -3.141593f;
public const float Float_E = (float)Math.E;
public const float Float_Negated_E = -(float)Math.E;
@ -117,6 +121,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -117,6 +121,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public const double Double_LooksLikePI = 3.1415926;
public const double Double_LooksLikePI2 = 3.14159;
public const double Double_LooksLikePI3 = 3.141;
public const double Double_BeforePI = 3.1415926535897927;
public const double Double_AfterPI = 3.1415926535897936;
public const double Double_Negated_PI = -Math.PI;
public const double Double_Negated_HalfOfPI = -Math.PI / 2.0;
public const double Double_Negated_QuarterOfPI = -Math.PI / 4.0;
@ -131,8 +137,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -131,8 +137,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public const double Double_Negated_PITimes90 = Math.PI * -90.0;
public const double Double_Negated_PITimes180 = Math.PI * -180.0;
public const double Double_Negated_LooksLikePI = -3.141;
public const double Double_Negated_BeforePI = -3.1415926535897927;
public const double Double_Negated_AfterPI = -3.1415926535897936;
public const double Double_E = Math.E;
public const double Double_BeforeE = 2.7182818284590446;
public const double Double_AfterE = 2.7182818284590455;
public const double Double_Negated_E = -Math.E;
public const double Double_Negated_BeforeE = -2.7182818284590446;
public const double Double_Negated_AfterE = -2.7182818284590455;
}
}

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.il

@ -126,6 +126,8 @@ @@ -126,6 +126,8 @@
.field public static literal float64 Double_LooksLikePI = float64(3.1415926000000001)
.field public static literal float64 Double_LooksLikePI2 = float64(3.1415899999999999)
.field public static literal float64 Double_LooksLikePI3 = float64(3.141)
.field public static literal float64 Double_BeforePI = float64(3.1415926535897927)
.field public static literal float64 Double_AfterPI = float64(3.1415926535897936)
.field public static literal float64 Double_Negated_PI = float64(-3.1415926535897931)
.field public static literal float64 Double_Negated_HalfOfPI = float64(-1.5707963267948966)
.field public static literal float64 Double_Negated_QuarterOfPI = float64(-0.78539816339744828)
@ -140,8 +142,14 @@ @@ -140,8 +142,14 @@
.field public static literal float64 Double_Negated_PITimes90 = float64(-282.74333882308139)
.field public static literal float64 Double_Negated_PITimes180 = float64(-565.48667764616278)
.field public static literal float64 Double_Negated_LooksLikePI = float64(-3.141)
.field public static literal float64 Double_Negated_BeforePI = float64(-3.1415926535897927)
.field public static literal float64 Double_Negated_AfterPI = float64(-3.1415926535897936)
.field public static literal float64 Double_E = float64(2.7182818284590451)
.field public static literal float64 Double_BeforeE = float64(2.7182818284590446)
.field public static literal float64 Double_AfterE = float64(2.7182818284590455)
.field public static literal float64 Double_Negated_E = float64(-2.7182818284590451)
.field public static literal float64 Double_Negated_BeforeE = float64(-2.7182818284590446)
.field public static literal float64 Double_Negated_AfterE = float64(-2.7182818284590455)
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.opt.il

@ -126,6 +126,8 @@ @@ -126,6 +126,8 @@
.field public static literal float64 Double_LooksLikePI = float64(3.1415926000000001)
.field public static literal float64 Double_LooksLikePI2 = float64(3.1415899999999999)
.field public static literal float64 Double_LooksLikePI3 = float64(3.141)
.field public static literal float64 Double_BeforePI = float64(3.1415926535897927)
.field public static literal float64 Double_AfterPI = float64(3.1415926535897936)
.field public static literal float64 Double_Negated_PI = float64(-3.1415926535897931)
.field public static literal float64 Double_Negated_HalfOfPI = float64(-1.5707963267948966)
.field public static literal float64 Double_Negated_QuarterOfPI = float64(-0.78539816339744828)
@ -140,8 +142,14 @@ @@ -140,8 +142,14 @@
.field public static literal float64 Double_Negated_PITimes90 = float64(-282.74333882308139)
.field public static literal float64 Double_Negated_PITimes180 = float64(-565.48667764616278)
.field public static literal float64 Double_Negated_LooksLikePI = float64(-3.141)
.field public static literal float64 Double_Negated_BeforePI = float64(-3.1415926535897927)
.field public static literal float64 Double_Negated_AfterPI = float64(-3.1415926535897936)
.field public static literal float64 Double_E = float64(2.7182818284590451)
.field public static literal float64 Double_BeforeE = float64(2.7182818284590446)
.field public static literal float64 Double_AfterE = float64(2.7182818284590455)
.field public static literal float64 Double_Negated_E = float64(-2.7182818284590451)
.field public static literal float64 Double_Negated_BeforeE = float64(-2.7182818284590446)
.field public static literal float64 Double_Negated_AfterE = float64(-2.7182818284590455)
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.opt.roslyn.il

@ -130,6 +130,8 @@ @@ -130,6 +130,8 @@
.field public static literal float64 Double_LooksLikePI = float64(3.1415926000000001)
.field public static literal float64 Double_LooksLikePI2 = float64(3.1415899999999999)
.field public static literal float64 Double_LooksLikePI3 = float64(3.141)
.field public static literal float64 Double_BeforePI = float64(3.1415926535897927)
.field public static literal float64 Double_AfterPI = float64(3.1415926535897936)
.field public static literal float64 Double_Negated_PI = float64(-3.1415926535897931)
.field public static literal float64 Double_Negated_HalfOfPI = float64(-1.5707963267948966)
.field public static literal float64 Double_Negated_QuarterOfPI = float64(-0.78539816339744828)
@ -144,8 +146,14 @@ @@ -144,8 +146,14 @@
.field public static literal float64 Double_Negated_PITimes90 = float64(-282.74333882308139)
.field public static literal float64 Double_Negated_PITimes180 = float64(-565.48667764616278)
.field public static literal float64 Double_Negated_LooksLikePI = float64(-3.141)
.field public static literal float64 Double_Negated_BeforePI = float64(-3.1415926535897927)
.field public static literal float64 Double_Negated_AfterPI = float64(-3.1415926535897936)
.field public static literal float64 Double_E = float64(2.7182818284590451)
.field public static literal float64 Double_BeforeE = float64(2.7182818284590446)
.field public static literal float64 Double_AfterE = float64(2.7182818284590455)
.field public static literal float64 Double_Negated_E = float64(-2.7182818284590451)
.field public static literal float64 Double_Negated_BeforeE = float64(-2.7182818284590446)
.field public static literal float64 Double_Negated_AfterE = float64(-2.7182818284590455)
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.roslyn.il

@ -130,6 +130,8 @@ @@ -130,6 +130,8 @@
.field public static literal float64 Double_LooksLikePI = float64(3.1415926000000001)
.field public static literal float64 Double_LooksLikePI2 = float64(3.1415899999999999)
.field public static literal float64 Double_LooksLikePI3 = float64(3.141)
.field public static literal float64 Double_BeforePI = float64(3.1415926535897927)
.field public static literal float64 Double_AfterPI = float64(3.1415926535897936)
.field public static literal float64 Double_Negated_PI = float64(-3.1415926535897931)
.field public static literal float64 Double_Negated_HalfOfPI = float64(-1.5707963267948966)
.field public static literal float64 Double_Negated_QuarterOfPI = float64(-0.78539816339744828)
@ -144,8 +146,14 @@ @@ -144,8 +146,14 @@
.field public static literal float64 Double_Negated_PITimes90 = float64(-282.74333882308139)
.field public static literal float64 Double_Negated_PITimes180 = float64(-565.48667764616278)
.field public static literal float64 Double_Negated_LooksLikePI = float64(-3.141)
.field public static literal float64 Double_Negated_BeforePI = float64(-3.1415926535897927)
.field public static literal float64 Double_Negated_AfterPI = float64(-3.1415926535897936)
.field public static literal float64 Double_E = float64(2.7182818284590451)
.field public static literal float64 Double_BeforeE = float64(2.7182818284590446)
.field public static literal float64 Double_AfterE = float64(2.7182818284590455)
.field public static literal float64 Double_Negated_E = float64(-2.7182818284590451)
.field public static literal float64 Double_Negated_BeforeE = float64(-2.7182818284590446)
.field public static literal float64 Double_Negated_AfterE = float64(-2.7182818284590455)
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

95
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -930,9 +930,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -930,9 +930,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
const int MAX_DENOMINATOR = 1000;
const double DOUBLE_THRESHOLD = 1e-10;
const float FLOAT_THRESHOLD = 1e-10f;
Expression ConvertFloatingPointLiteral(IType type, object constantValue)
{
bool isDouble = type.IsKnownType(KnownTypeCode.Double);
@ -963,8 +960,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -963,8 +960,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
if (expr == null) {
(long num, long den) = isDouble
? DoubleFractionApprox((double)constantValue, MAX_DENOMINATOR)
: FloatFractionApprox((float)constantValue, MAX_DENOMINATOR);
? FractionApprox((double)constantValue, MAX_DENOMINATOR)
: FractionApprox((float)constantValue, MAX_DENOMINATOR);
if (IsValidFraction(num, den) && Math.Abs(num) != 1 && Math.Abs(den) != 1) {
var left = MakeConstant(type, num);
@ -1025,12 +1022,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1025,12 +1022,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
if (isDouble) {
if (Math.Abs((double)literalValue - (memberName == "PI" ? Math.PI : Math.E) * n / d) < DOUBLE_THRESHOLD)
double approxValue = n / (double)d * (memberName == "PI" ? Math.PI : Math.E);
if (approxValue == (double)literalValue)
return expr;
} else {
float approxValue = (memberName == "PI" ? MathF_PI : MathF_E) * n / d;
float diff = (float)literalValue - approxValue;
if ((float)Math.Abs(diff) < FLOAT_THRESHOLD)
float approxValue = n / (float)d * (memberName == "PI" ? MathF_PI : MathF_E);
if (approxValue == (float)literalValue)
return expr;
}
@ -1042,12 +1039,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1042,12 +1039,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
if (isDouble) {
if (Math.Abs((double)literalValue - (n / (d * (memberName == "PI" ? Math.PI : Math.E)))) < DOUBLE_THRESHOLD)
double approxValue = n / (d * (memberName == "PI" ? Math.PI : Math.E));
if (approxValue == (double)literalValue)
return expr;
} else {
float approxValue = n / (d * (memberName == "PI" ? MathF_PI : MathF_E));
float diff = (float)literalValue - approxValue;
if ((float)Math.Abs(diff) < FLOAT_THRESHOLD)
if (approxValue == (float)literalValue)
return expr;
}
@ -1055,16 +1052,16 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1055,16 +1052,16 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
(long num, long den) = isDouble
? DoubleFractionApprox((double)literalValue / (memberName == "PI" ? Math.PI : Math.E), MAX_DENOMINATOR)
: FloatFractionApprox((float)literalValue / (memberName == "PI" ? MathF_PI : MathF_E), MAX_DENOMINATOR);
? FractionApprox((double)literalValue / (memberName == "PI" ? Math.PI : Math.E), MAX_DENOMINATOR)
: FractionApprox((float)literalValue / (memberName == "PI" ? MathF_PI : MathF_E), MAX_DENOMINATOR);
if (IsValidFraction(num, den)) {
return ExtractExpression(num, den);
}
(num, den) = isDouble
? DoubleFractionApprox((double)literalValue * (memberName == "PI" ? Math.PI : Math.E), MAX_DENOMINATOR)
: FloatFractionApprox((float)literalValue * (memberName == "PI" ? MathF_PI : MathF_E), MAX_DENOMINATOR);
? FractionApprox((double)literalValue * (memberName == "PI" ? Math.PI : Math.E), MAX_DENOMINATOR)
: FractionApprox((float)literalValue * (memberName == "PI" ? MathF_PI : MathF_E), MAX_DENOMINATOR);
if (IsValidFraction(num, den)) {
return ExtractExpression(num, den);
@ -1073,7 +1070,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1073,7 +1070,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return null;
}
#region FractionApprox
// based on https://www.ics.uci.edu/~eppstein/numth/frap.c
// find rational approximation to given real number
// David Eppstein / UC Irvine / 8 Aug 1993
@ -1094,7 +1090,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1094,7 +1090,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
// ( 1 0 ) ( 1 0 ) ( 1 0 )
// Instead of keeping the sequence of continued fraction terms,
// we just keep the last partial product of these matrices.
static (long Num, long Den) DoubleFractionApprox(double value, int maxDenominator)
static (long Num, long Den) FractionApprox(double value, int maxDenominator)
{
if (value > 0x7FFFFFFF)
return (0, 0);
@ -1102,7 +1098,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1102,7 +1098,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
double startValue = value;
if (value < 0)
value = -value;
bool IsValid(long num, long den) => den > 0 && (double)Math.Abs(value - num / (double)den) < DOUBLE_THRESHOLD;
long ai;
long[,] m = new long[2, 2];
@ -1127,65 +1122,21 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1127,65 +1122,21 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
if (m[1, 0] == 0)
return (0, 0);
if (!IsValid(num: m[0, 0], den: m[1, 0])) {
ai = (maxDenominator - m[1, 1]) / m[1, 0];
m[0, 0] = m[0, 0] * ai + m[0, 1];
m[1, 0] = m[1, 0] * ai + m[1, 1];
}
if (!IsValid(num: m[0, 0], den: m[1, 0]))
return (0, 0);
return ((startValue < 0 ? -m[0, 0] : m[0, 0]), m[1, 0]);
}
static (long Num, long Den) FloatFractionApprox(float value, int maxDenominator)
{
if (value > 0x7FFFFFFF)
return (0, 0);
float startValue = value;
if (value < 0)
value = -value;
bool IsValid(long num, long den) => den > 0 && (float)Math.Abs(value - num / (float)den) < 1e-9f;
long ai;
long[,] m = new long[2, 2];
m[0, 0] = m[1, 1] = 1;
m[0, 1] = m[1, 0] = 0;
float v = value;
while (m[1, 0] * (ai = (long)v) + m[1, 1] <= maxDenominator) {
long t = m[0, 0] * ai + m[0, 1];
m[0, 1] = m[0, 0];
m[0, 0] = t;
t = m[1, 0] * ai + m[1, 1];
m[1, 1] = m[1, 0];
m[1, 0] = t;
if (v - ai == 0) break;
v = 1 / (v - ai);
if (Math.Abs(v) > long.MaxValue) break; // value cannot be stored in fraction without overflow
}
if (m[1, 0] == 0)
return (0, 0);
long firstN = m[0, 0];
long firstD = m[1, 0];
if (!IsValid(num: m[0, 0], den: m[1, 0])) {
ai = (maxDenominator - m[1, 1]) / m[1, 0];
m[0, 0] = m[0, 0] * ai + m[0, 1];
m[1, 0] = m[1, 0] * ai + m[1, 1];
}
long secondN = m[0, 0] * ai + m[0, 1];
long secondD = m[1, 0] * ai + m[1, 1];
if (!IsValid(num: m[0, 0], den: m[1, 0]))
return (0, 0);
double firstDelta = Math.Abs(value - firstN / (double)firstD);
double secondDelta = Math.Abs(value - secondN / (double)secondD);
return (startValue < 0 ? -m[0, 0] : m[0, 0], m[1, 0]);
if (firstDelta < secondDelta)
return (startValue < 0 ? -firstN : firstN, firstD);
return (startValue < 0 ? -secondN : secondN, secondD);
}
#endregion
#endregion
#region Convert Parameter
public ParameterDeclaration ConvertParameter(IParameter parameter)

Loading…
Cancel
Save