intellij-community icon indicating copy to clipboard operation
intellij-community copied to clipboard

[Fernflower] Improve output for float and double literals

Open Pokechu22 opened this issue 7 years ago • 0 comments

This PR does a few things regarding float and double literals:

  • Adds support for Float.MIN_NORMAL and Double.MIN_NORMAL, added in Java 1.6
  • Fixed invalid code being generated for Float.NaN, Float.POSITIVE_INFINITY, and Float.NEGATIVE_INFINITY when literals-as-is is enabled (-lit=1), which all used 0.0 for the denominator causing the expression to be a double instead of a float. 0.0F is now used, and 0.0D is used for the double versions.
  • Negative MAX_VALUE and similar are decompiled now, so -Double.MAX_VALUE is produced instead of -1.7976931348623157e+308.
  • Math.E is now regenerated, instead of producing 2.7182818284590452354
  • Math.PI is now regenerated, along with various common factors of it.
    • The float version is recorded as (float)Math.PI for 3.1415927F. This is likely to occur if a program defines its own constant that is a float version of pi and uses that.
  • Cases where a float literal was used to assign a double are now properly detected, so that (double)0.01F is output instead of 0.009999999776482582D. This is only applied in cases where the float value is shorter than the double value, so 1.0D is not changed to (double)1.0F.
    • This also applies to the other constants, so (double)((float)Math.PI / 4F) is produced instead of 0.7853981852531433D. This is a bit ugly due to the double casting, but it's the easiest way to make sure it's not ambiguous.

With regards to possible future work on this, there are two things I can think of:

  • PI_DOUBLES and PI_FLOATS are a bit awkward, and I think a more general way of handling fractions would work better than them; however I don't know of any easy method for doing this.
  • The casting from a float literal to a double is a bit of a mess, and it would be nice if it could be avoided if it was known that it would be ambiguous. However I don't think there's an easy way of doing this at this time.

Previously submitted to a fork at MinecraftForge/ForgeFlower#24. I meant to upstream this a while back but I was busy and then forgot about it. This does have a few differences from that: I did a bigger diff here; I have unit tests; and also negative MAX_VALUE/MIN_VALUE/etc are supported (which was done later in MinecraftForge/ForgeFlower#37).

Pokechu22 avatar Sep 30 '18 21:09 Pokechu22