-
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
- Give yourself a Bundle
- Give yourself 30 items with a max stack size of 31: /give @s minecraft:cobblestone[minecraft:max_stack_size=31] 30
- Add those items to the Bundle
- Notice how it says 61/64 (the equivalent of floor((30/31) * 64))
- Add 2 item stacks with a max stack size of 64 to the Bundle
- Notice how it says 63/64
- Try to add another item stack with a max stack size of 64
- 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()); }