Skip to content

大型箱子防溢出保护与数学安全

整数溢出问题

在 Java 和 Minecraft 底层,物品栏堆叠计算使用 32 位有符号整数(int)。32 位有符号整数能表示的最大数值为: $$I_{\max} = 2^{31} - 1 = 2,147,483,647$$

当一个拥有 54 个槽位的大箱子装满达到上限的物品时,计算容器内部的物品总数需要对全部 54 个槽位进行求和。


🧮 安全阈值计算

如果 54 槽位大箱子中的每个槽位都容纳上限为 $L$ 的堆叠: $$\text{箱子总物品数} = 54 \times L$$

为保证 $\text{箱子总物品数}$ 不超过 $I_{\max}$: $$54 \times L \le 2,147,483,647$$ $$L \le \frac{2,147,483,647}{54} \approx 39,768,215.68$$

因此,堆叠限制的绝对安全阈值为: $$L_{\text{safe}} = 39,768,215$$

溢出影响对照表

堆叠上限 ($L$)54 槽位大箱子总物品数整数状态风险等级
128(默认值)$6,912$安全 ($< 21.4\text{ 亿}$)零风险
1,000,000$54,000,000$安全 ($< 21.4\text{ 亿}$)零风险
39,768,215$2,147,483,610$安全 ($< 21.4\text{ 亿}$)推荐最高安全上限
40,000,000$2,160,000,000$发生溢出!(回绕至 $-2,134,967,296$)物品消失 / 容器数据损坏

🛠️ 双精度快速合成数学计算

AbstractContainerMenuMixin 中,原版的快速合成除法运算被重写为采用 64 位 double 双精度浮点数学,防止在拖动超大堆叠时发生精度丢失和负数回绕:

java
@Mixin(AbstractContainerMenu.class)
public class AbstractContainerMenuMixin {
    @Overwrite
    public static int getQuickCraftPlaceCount(int quickCraftSlotsSize, int quickCraftingType, ItemStack itemStack) {
        return switch (quickCraftingType) {
            case 0 -> (int) ((double) itemStack.getCount() / (double) quickCraftSlotsSize);
            case 1 -> 1;
            case 2 -> itemStack.getMaxStackSize();
            default -> itemStack.getCount();
        };
    }
}

Official documentation & web portal for Dasik Igaijinn mods.