Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-259032

/data produces a positive result for low negative numbers

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.19.3, 23w04a, 1.20 Release Candidate 1, 1.20, 23w35a, 1.20.3, 1.20.4 Release Candidate 1, 1.20.4, 23w51b, 24w03a, 24w04a, 24w05a, 24w06a, 24w07a
    • None
    • Confirmed
    • Commands
    • Normal
    • Platform

      When you apply a /data get command to a value that is smaller than -2147483648 (-231, the lowest int value), it returns a result of 2147483647 (231-1, the highest int value).

      Explanation:

      For the result of the /data get command, the following function is used to convert into an integer:

      public static int floor(double x) {
          int i = (int) x;
          return x < i ? x - 1 : x;
      }
      

      The first line in the function removes the digits after the decimal point. Since the int type only provides the fixed range between -2147483648 (-231) and 2147483647 (231-1), any values above or below are reduced to this maximum or minimum, meaning that any values below -231 are converted to exactly -231.

      The problem then occurres in the second line, which will, in the case of such a low number, say yes, x is smaller than -231 and try to subtract 1. Since the number is already the smallest possible, this will cause the number to underflow and wrap around to the maximum value (231-1).

      Implications:

      A usually good approach to determining whether a numeric tag is negative is to take its /data get result and determine whether that is negative. This approach stops working because of this bug. In fact, there is currently no simple approach that works for all numbers (except for using number to string conversion in function macros, which is much slower and tedious).

      Possible fix:

      Change the implementation of net.minecraft.util.Mth.floor to this:

      public static int floor(double x) {
          return (int) Math.floor(x);
      }
      

      This produces the desired output and fixes the bug. For any performance considerations, it seems to be approximately as fast as the current approach, maybe slightly slower.

      Steps to Reproduce:
      1. Create an NBT tag with a value below -231, e.g.

      /data modify storage test:test value set value -3.0e9d
      

      2. Run /data get and store its result using /execute store:

      /execute store result storage test:test result int 1 run data get storage test:test value
      

      3. Retrieve the result

      /data get storage test:test result
      

      The result will be 2147483647 (a positive integer), while it should be a negative integer like -2147483648.

            Unassigned Unassigned
            Rob23 Rob23
            Votes:
            5 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              CHK: