Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 一种计算任意大整数的整数平方根(isqrt)的有效算法 通知_Algorithm_Erlang_Biginteger_Bigint_Square Root - Fatal编程技术网

Algorithm 一种计算任意大整数的整数平方根(isqrt)的有效算法 通知

Algorithm 一种计算任意大整数的整数平方根(isqrt)的有效算法 通知,algorithm,erlang,biginteger,bigint,square-root,Algorithm,Erlang,Biginteger,Bigint,Square Root,有关Erlang或C/C++中的解决方案,请转到下面的试用版4 维基百科文章 “整数平方根”的定义可以在这里找到 在这里可以找到一个具有“比特魔法”的算法 [试用版1:使用库函数] 代码 当erlang:is_integer(N),N>=0-> erlang:trunc(数学:sqrt(N))。 问题 此实现使用C库中的sqrt()函数,因此不能处理任意大的整数(请注意,返回的结果与输入不匹配。正确答案应为123456789012134567890): [试用版2:仅使用Bi

有关
Erlang
C/C++
中的解决方案,请转到下面的试用版4


维基百科文章

  • “整数平方根”的定义可以在这里找到

  • 在这里可以找到一个具有“比特魔法”的算法

[试用版1:使用库函数] 代码 当erlang:is_integer(N),N>=0-> erlang:trunc(数学:sqrt(N))。 问题 此实现使用C库中的
sqrt()
函数,因此不能处理任意大的整数(请注意,返回的结果与输入不匹配。正确答案应为
123456789012134567890
):


[试用版2:仅使用Bigint
+
] 代码 当erlang:is_integer(N),N>=0-> isqrt2(N,0,3,0)。 当I>=N-> 结果; isqrt2(N,I,次,结果)-> isqrt2(N,I+次,次+2,结果+1)。 描述 该实施基于以下观察结果:

isqrt(0)=0#
中=(低+高)第2部分,
MidSqr=Mid*Mid,
如果
%%这也会捕获N=0或1
MidSqr=:=N->
中间;
MidSqr
isqrt3(N、中、高);
MidSqr>N->
isqrt3(北、低、中)
结束。
变量2(修改上述代码,使边界以Mid+1或Mid-1代替,参考 当erlang:is_integer(N),N>=0-> isqrt3a(N,1,N)。 isqrt3a(N,低,高)当低>=高-> HighSqr=高*高, 如果 高SQR>N-> 高-1; 高SQR= 高 结束; isqrt3a(N、低、高)-> 中=(低+高)第2部分, MidSqr=Mid*Mid, 如果 %%这也会捕获N=0或1 MidSqr=:=N-> 中间; MidSqr isqrt3a(N,中+1,高); MidSqr>N-> isqrt3a(N、低、中-1) 结束。 问题 现在它求解闪电速度中的79位数字(即
1111111111111111111111111111111111*1111111111111111111111111111111111111
),结果立即显示。然而,在我的机器上,求解一百万(1000000)个61位数字(即从
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000。我想做得更快


[试验4:仅对Bigint
+
div使用牛顿法]
代码
isqrt4(0)->0;
isqrt4(N)当erlang:is_integer(N),N>=0->
isqrt4(N,N)。
isqrt4(N,Xk)->
Xk1=(Xk+N分区Xk)分区2,
如果
Xk1>=Xk->
Xk;
Xk1
isqrt4(N,Xk1)
结束。
C/C++代码(为了您的兴趣) 递归变量
#包括
uint32\u t isqrt\u impl(
uint64_t const n,
uint64_t const xk)
{
uint64_t const xk1=(xk+n/xk)/2;
返回(xk1>=xk)?xk:isqrt_impl(n,xk1);
}
uint32\u t isqrt(uint64\u t const n)
{
如果(n==0)返回0;
如果(n==18446744073709551615ULL)返回4294967295U;
返回isqrt_impl(n,n);
}
迭代变量
#包括
uint32是迭代的(uint64常数)
{
uint64_t xk=n;
如果(n==0)返回0;
如果(n==18446744073709551615ULL)返回4294967295U;
做
{
uint64_t const xk1=(xk+n/xk)/2;
如果(xk1>=xk)
{
返回xk;
}
其他的
{
xk=xk1;
}
}而(1),;
}
问题 Erlang代码在我的机器上用40秒(+-1秒)的时间解出100万(1000000)个61位数字,因此比试用版3快。它能跑得更快吗


关于我的机器 处理器:3.4 GHz Intel Core i7

内存:32 GB 1600 MHz DDR3

操作系统:Mac OS X 10.9.1版


相关问题

  • 使用“牛顿法”。我不确定使用“整数除法”进行除法是否可以。我稍后将尝试此更新。[更新(2015-01-11):可以这样做]

  • 这涉及到使用第三方Python包
    gmpy
    ,这对我来说不是很有利,因为我主要感兴趣的是在Erlang中使用内置工具来解决它

  • 这看起来很有趣。我真的不明白到底发生了什么,但似乎这里涉及到了“比特魔法”,所以它也不太适合我

    这个问题是针对C++的,AraK(提问者)的算法看起来像是与上面的试验2相同的想法。
像下面这样的二进制搜索不需要浮点除法,只需要整数乘法(比牛顿法慢):-

注意:
acc/10
是整数除法

编辑:-

bound = 1;
acc = N;
count = 0;
while(acc>0) {

 acc = acc/10;

 if(count%2==0) {

    bound = bound*10;
 }

 count++;

}

high = bound*10;
low = bound/10;
isqrt(N,low,high);
有效边界:-sqrt(n)的位数约为n的一半,因此您可以通过
high=10^(log10(n)/2+1)
low=10^(log10(n)/2-1)
来获得更紧密的边界,并且它应该提供2倍的加速

计算边界:-

bound = 1;
acc = N;
count = 0;
while(acc>0) {

 acc = acc/10;

 if(count%2==0) {

    bound = bound*10;
 }

 count++;

}

high = bound*10;
low = bound/10;
isqrt(N,low,high);

/
在Python中是整数除法,所以牛顿关于
x^2-n=0
的方法很有效。@Blender:我知道
/
在Python中的意思,因此我怀疑它是否有效,因为维基百科上发布的算法(以及任何与“牛顿方法”相关的东西)都适用于实数(注意关于浮点的脚注).使用整数除法没有任何区别。序列{x_n}以
isqrt(n)
@Blender的最大下界递减:应用Wikiped的算法
acc = target

log10 = 0;

while(acc>0) {

  log10 = log10 + 1;
  acc = acc/10;
}
bound = 1;
acc = N;
count = 0;
while(acc>0) {

 acc = acc/10;

 if(count%2==0) {

    bound = bound*10;
 }

 count++;

}

high = bound*10;
low = bound/10;
isqrt(N,low,high);