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

Bundle shows incorrect occupancy for stack sizes that are not factors of 64

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • None
    • 24w14a
    • None
    • Confirmed
    • (Unassigned)

      The Bundle item shows an incorrect occupancy for max stack sizes that are not factors of 64, i.e. any number but 1, 2, 4, 8, 16, 32 and 64. For example, 30 items with a max stack size of 31 shows as 61/64, despite (30/31) * 64 ≈ 61.94, which should round up to 62, as only two more item stacks with a max stack size of 64 can be added to the bundle. Currently it truncates the number due to integer division. (In actuality it floors the number, as the input, the occupancy, is always non-negative.)

      Steps to reproduce

      1. Give yourself a Bundle
      2. Give yourself 30 items with a max stack size of 31: /give @s minecraft:cobblestone[minecraft:max_stack_size=31] 30
      3. Add those items to the Bundle
      4. Notice how it says 61/64 (the equivalent of floor((30/31) * 64))
      5. Add 2 item stacks with a max stack size of 64 to the Bundle
      6. Notice how it says 63/64
      7. Try to add another item stack with a max stack size of 64
      8. Notice how it does not add the item, despite the Bundle showing that it has room for one more

      The Bundle can't actually add another item, as ((30/31) + (2/64)) * 64 ≈ 63.96, which means it has room for less than one item. It's just the displayed value that is incorrect.

      Code analysis

      The Mth::mulAndTruncate method does integer division, which means it truncates the resulting number. (It... does what it says it does.)

      public static int mulAndTruncate(Fraction fraction, int multiplier) {
      	return fraction.getNumerator() * multiplier / fraction.getDenominator();
      }
      

      This can be fixed by using a floating point number and using a ceiling method to round the value up, for example by using the following:

      public static int mulAndCeil(Fraction fraction, int multiplier) {
      	// How convenient, the method exists already in the Mth class
      	return Mth.ceil(fraction.getNumerator() * (double) multiplier / fraction.getDenominator());
      }
      

      Alternatively Fraction::multiplyBy can be used as to only convert the resulting number to a double:

      public static int mulAndCeil(Fraction fraction, int multiplier) {
      	return Mth.ceil(fraction.multiplyBy(Fraction.getFraction(multiplier, 1)).doubleValue());
      }
      

            Unassigned Unassigned
            ErrorCraft ErrorCraft
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: