Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.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
在C+中实现双sqrt(双x)+; 在C++中使用双Sqt(double x)< /C> >,不使用STD库。< /P>_C++_Sqrt - Fatal编程技术网

在C+中实现双sqrt(双x)+; 在C++中使用双Sqt(double x)< /C> >,不使用STD库。< /P>

在C+中实现双sqrt(双x)+; 在C++中使用双Sqt(double x)< /C> >,不使用STD库。< /P>,c++,sqrt,C++,Sqrt,这是我在这里看到的一个facebook采访问题。 还有什么好主意吗 !!!编辑。!!!(不使用std库。)这里是可以在上找到的最优秀的genius sqrt实现之一。这不是最准确的,但速度非常快 float fast_sqrt(float number) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long *

这是我在这里看到的一个facebook采访问题。 还有什么好主意吗


!!!编辑。!!!(不使用std库。)

这里是可以在上找到的最优秀的genius sqrt实现之一。这不是最准确的,但速度非常快

float fast_sqrt(float number) {
   long i;
   float x2, y;
   const float threehalfs = 1.5F;

   x2 = number * 0.5F;
   y  = number;
   i  = * ( long * ) &y;                     // floating point bit level hacking [sic]
   i  = 0x5f3759df - ( i >> 1 );             // Newton's approximation
   y  = * ( float * ) &i;
   y  = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
   y  = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration
   y  = y * ( threehalfs - ( x2 * y * y ) ); // 3rd iteration

   return 1/y;
}

两个明显的答案是对分(半慢)和牛顿-拉斐逊/莱布尼兹迭代(通常更快)。为了不破坏任何人的乐趣,我将重新解释这个问题——下面是8086汇编语言中使用Newton Raphson技术实现的整数平方根:

isqrt proc uses di, number:word
;
; uses bx, cx, dx
;
    mov di,number
    mov ax,255
start_loop:
    mov bx,ax
    xor dx,dx
    mov ax,di
    div bx
    add ax,bx
    shr ax,1
    mov cx,ax
    sub cx,bx
    cmp cx,2
    ja  start_loop
    ret
isqrt endp
这有一些改进——它使用x/2作为它在sqrt(x)上的初始猜测。使用386+指令,您可以使用
bsr
查找设置为获得log2x粗略近似值的最高有效位,并将其除以2以获得初始近似值


OTOH,这只有在古代处理器上才有意义。自从486(或更多)内置浮点硬件以来,几乎可以肯定的是,
FSQRT
指令将击败这条指令(或几乎任何您可以编写的指令)。

看。这篇CodeProject文章比较了计算平方根的14种不同方法。

如果允许我使用log(ln)和exp,那么exp(log(x)/2)当然会给出平方根

假设不是:

如果我们的值是x的sqrt,开始值是y,那么我们迭代y->(y+x/y)/2

终止条件可能是y接近其先前值,或者是y*y接近x

以385作为我的x值,我在迭代(Excel)中获得这些值

您可以使用“近似”2^(对数基数2(x)/2)作为起点,而不是1。 385的日志在8到9之间,所以如果我们说8.5,那么从2^4.25开始。如果我们在16和32之间做线性,那么我们将从20开始

从20开始,我只需4个步骤即可实现:

20
19.625
19.6214172
19.62141687

但是它需要以前的“迭代”来计算近似的对数和指数。

#include
[newline]
double-sqrt(double-x){return-std::sqrt(x);}
@James:I在想
include
[newline]
double-sqrt(double-x){return std::pow(x,0.5)}
这肯定是最愚蠢的面试问题之一。他们想要一个有C++能力的人或者有人知道算法,这很容易被查到吗?你的意思是告诉我们你认为面试应该是什么?他想要这份工作吗?你应该试着在面试中给他们留下深刻印象。@Tony:“我会使用来自Quake的快速平方根逆函数的方法——这个公式太神奇了——你知道它是不是?”可能就足够了。(虽然从技术上讲,这做了3次牛顿-拉斐逊近似,而不是1次…所以这不完全是同一件事)哦,是的,我添加了这些以获得更高的精度,但忘了将它们去掉。基本上和tho一样。@regality:我对整数使用了这种方法,对于32位,一次迭代就足以达到100%的精度(随机数和包括边),您是否检查了
float
的额外迭代?据我所知,使用倒数方法更快,可能是因为它用聪明的黑客代替了循环。但是我不确定它的精度。@Matthieu M:是的,如果你改变这个问题,你可以稍微提高速度。他们中的大多数人也做了一个非常粗糙的近似,仅适用于大约10或12位(在典型分辨率下仍然是~1像素)。然而,对于一个实际的平方根来说,它真的很难打败专用硬件。是的,很明显,但我指的是你写的汇编函数:)我使用了对整数具有完美精度的倒数方法,我猜添加一些牛顿迭代会在某种程度上提高精度。有趣的是得到了一个很好的一次近似值,然后可以根据需要改进精度。
20
19.625
19.6214172
19.62141687