【MC】用命令做一个简易的开根号
小豆8593
2020年04月26日 16:48

mc原版的记分板指令operation是没有开根号的计算的

但是很多时候这个运算又很有用,我们在原版怎么实现它呢?

一般情况下,保留整数即可满足需求。常用的方法为二分法。

更高精度的开根号算法请参考小豆数学库:https://www.mcbbs.net/thread-994925-1-1.html

这里我们利用另外一种算法。(迭代式与牛顿迭代完全一致,只不过从另外一种角度理解)

令f(x)=1/2(x+k/x),x>0,k>0。利用中学知识可知,这是一个对勾函数的一支。

对勾函数及其不动点、系数k开根号

那么这个函数有什么特殊之处呢?

我们求一下它的不动点。f(x)=x,可得:根号k是它的不动点。

结合图像特点,我们可以从x>0的任意位置插值,不断逼近它的不动点。

如:令k=4,f(1)=2.5,f(f(1))=2.05,f(f(f(1)))=2.0006097560976......

迭代的结果越来越接近根号4也就是2。

由记分板的上限2147483647,我们可以先适当估计结果的取值范围,插入初始值,迭代几次便可很好地得到结果。

特别地,当k=0,它也会逐渐逼近0。

以下是命令部分:

#获取输入,若小于0则取绝对值。

scoreboard players operation stempk int = input int

execute if score stempk int matches ..-1 run scoreboard players operation stempk int *= -1 int

#估计根的范围,插值

execute if score stempk int >= 1 int run scoreboard players set stempn int 1

execute if score stempk int >= 10 int run scoreboard players set stempn int 3

execute if score stempk int >= 100 int run scoreboard players set stempn int 10

execute if score stempk int >= 1000 int run scoreboard players set stempn int 30

execute if score stempk int >= 10000 int run scoreboard players set stempn int 100

execute if score stempk int >= 100000 int run scoreboard players set stempn int 300

execute if score stempk int >= 1000000 int run scoreboard players set stempn int 1000

execute if score stempk int >= 10000000 int run scoreboard players set stempn int 3000

execute if score stempk int >= 100000000 int run scoreboard players set stempn int 10000

execute if score stempk int >= 1000000000 int run scoreboard players set stempn int 30000

连续迭代6次(实测6次是保证无误差的最少次数),最后一次利用store将结果赋值result

scoreboard players operation stemp int = stempk int

scoreboard players operation stemp int /= stempn int

scoreboard players operation stempn int += stemp int

scoreboard players operation stempn int /= 2 int

scoreboard players operation stemp int = stempk int

scoreboard players operation stemp int /= stempn int

scoreboard players operation stempn int += stemp int

scoreboard players operation stempn int /= 2 int

scoreboard players operation stemp int = stempk int

scoreboard players operation stemp int /= stempn int

scoreboard players operation stempn int += stemp int

scoreboard players operation stempn int /= 2 int

scoreboard players operation stemp int = stempk int

scoreboard players operation stemp int /= stempn int

scoreboard players operation stempn int += stemp int

scoreboard players operation stempn int /= 2 int

scoreboard players operation stemp int = stempk int

scoreboard players operation stemp int /= stempn int

scoreboard players operation stempn int += stemp int

scoreboard players operation stempn int /= 2 int

scoreboard players operation stemp int = stempk int

scoreboard players operation stemp int /= stempn int

scoreboard players operation stempn int += stemp int

execute store result score result int run scoreboard players operation stempn int /= 2 int

只需执行36条命令。在-2147483647到2147483647的范围内无误差(指整数部分)