圣数11的出处是TaskHarvest::HarvestThing之中的某处逻辑BUG
这个函数首先定义几个参数
float num = base.target.Num;
float num2 = 1.1f;
if (text == "log" || text == "rock")
{
num2 = 2.2f;
}
if (base.target.trait is TraitAmmo)
{
num2 = 50f;
}
float num3 = num % num2;
num /= num2;
也就是,num: 当前物品数量,num2: 转化比例,num3:转化余数
可以看到,转化为log(原木)或者rock(岩石)的时候,转化比例变为2倍,也就是平均2.2个物品才能转化出一个原木或者岩石
多余的物品会被放置在转化余数num3中进行下一步的随机:
if (num3 > 0f && EClass.rndf(num2 - num3 + 1f) < 1f)
{
num += 1f;
}
看上去一切都很正常
然而,真的如此吗?
让我们计算一下圣数11:
11/1.1=10
11%1.1 = 1.0999998
稍有些计算机常识的人应该发现了,这里出现了舍入误差,舍入误差造成了一个本来应该是0的数(11%1.1应该是0)被错误舍入到了接近1.1
这导致了+1的发生
类似地,11 % 2.2 = 2.1999998,这是圣数11可以复制物品的来源
对箭矢类武器,系数是50,不存在舍入误差,因此也就不能触发类似的圣数复制效果
这个BUG的修复并不复杂,把1.1f和2.2f(准确地说,1.1000001430511474609375和2.200000286102294921875)改成1.099999904632568359375和2.19999980926513671875即可
总体来说是玩家赚了,因为在平均意义上,玩家在分解一千万个物品时,比之前大概能多获取一个材料
但
这个函数首先定义几个参数
float num = base.target.Num;
float num2 = 1.1f;
if (text == "log" || text == "rock")
{
num2 = 2.2f;
}
if (base.target.trait is TraitAmmo)
{
num2 = 50f;
}
float num3 = num % num2;
num /= num2;
也就是,num: 当前物品数量,num2: 转化比例,num3:转化余数
可以看到,转化为log(原木)或者rock(岩石)的时候,转化比例变为2倍,也就是平均2.2个物品才能转化出一个原木或者岩石
多余的物品会被放置在转化余数num3中进行下一步的随机:
if (num3 > 0f && EClass.rndf(num2 - num3 + 1f) < 1f)
{
num += 1f;
}
看上去一切都很正常
然而,真的如此吗?
让我们计算一下圣数11:
11/1.1=10
11%1.1 = 1.0999998
稍有些计算机常识的人应该发现了,这里出现了舍入误差,舍入误差造成了一个本来应该是0的数(11%1.1应该是0)被错误舍入到了接近1.1
这导致了+1的发生
类似地,11 % 2.2 = 2.1999998,这是圣数11可以复制物品的来源
对箭矢类武器,系数是50,不存在舍入误差,因此也就不能触发类似的圣数复制效果
这个BUG的修复并不复杂,把1.1f和2.2f(准确地说,1.1000001430511474609375和2.200000286102294921875)改成1.099999904632568359375和2.19999980926513671875即可
总体来说是玩家赚了,因为在平均意义上,玩家在分解一千万个物品时,比之前大概能多获取一个材料
但












