在 C++ 中实现 double sqrt(double x)
在 C++ 中实现 double sqrt(double x) 而不使用 std 库。
这是我在这里看到的一个 Facebook 面试问题。 http://www.glassdoor.com /采访/实现-double-sqrt-double-x-in-C-QTN_87210.htm 关于这个还有其他好主意吗?...
!编辑。!!!(不使用标准库。)
Implement double sqrt(double x)
in C++ without using std library.
This is a facebook interview question I saw here. http://www.glassdoor.com/Interview/Implement-double-sqrt-double-x-in-C-QTN_87210.htm
Any other good idea about this?...
!!!Edited.!!!(without using std library.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请查看此处。这篇 CodeProject 文章比较了 14 种不同的计算平方根的方法。
Look here. This CodeProject article compares 14 different methods for computing the square root.
两个明显的答案是二分法(半慢)和牛顿拉夫森/莱布尼兹迭代(通常更快)。为了避免破坏任何人的乐趣,我将对这个问题进行重新解释 - 这是使用 Newton-Raphson 技术在 8086 汇编语言中实现整数平方根的实现:
这有待一些改进 - 它使用 x/2作为对 sqrt(x) 的初始猜测。对于超过 386 条指令,您可以使用
bsr
查找设置为粗略近似 log2x 的最高有效位,并将其除以 2 以获得初始值近似。OTOH,这确实只对古代处理器有意义。对于自 486(或类似版本)以来具有内置浮点硬件的任何东西,几乎可以肯定
FSQRT
指令将击败它(或几乎任何您可以编写的其他指令)。The two obvious answers are bisection (semi-slow) and Newton-Raphson/Leibniz iteration (usually faster). To keep from spoiling anybody's fun, I'll do a reinterpret_cast on the question -- here's an implementation of an integer square root in 8086 assembly language using the Newton-Raphson technique:
This is open to some improvement -- it uses x/2 as its initial guess at the sqrt(x). With 386+ instructions, you can use
bsr
to find the most significant bit that's set to get a rough approximation of log2x, and divide that by 2 to get your initial approximation.OTOH, this really only made sense on ancient processors. For anything since the 486 (or so) that has built-in floating point hardware, it's nearly certain that the
FSQRT
instruction will beat this (or pretty much anything else you can write).这是最天才的 sqrt 实现之一,可以在 wikipedia 上找到。它不是最准确的,但速度非常快。
Here is one of the most genius sqrt implementations which can be found on wikipedia. It is not the most accurate, but extremely fast.
如果允许我使用 log (ln) 和 exp 那么 exp(log(x)/2) 当然会给我平方根。
假设不是:
如果我们发现 的 sqrt 是 x 并且起始值为 y,那么我们迭代 y->(y+x/y)/2
终止条件要么是 y 与其先前值的接近度,要么是y*y 到 x。
使用 385 作为我的 x 值,我在迭代中获得这些值 (Excel)
您可以使用“近似”2^(log base 2(x)/2) 作为起点而不是 1。
385 的对数介于 8 和 9 之间,因此如果我们说 8.5,则从 2^4.25 开始。如果我们在 16 和 32 之间做这个线性,那么我们将从 20 开始。
从 20 开始,我只需 4 步即可到达:
但它需要之前的“迭代”来计算近似对数和指数。
If I am allowed to use log (ln) and exp then of course exp(log(x)/2) will give me the square root.
Assuming not:
If our value we find the sqrt of is x and the start value is y then we iterate y->(y+x/y)/2
Terminating condition would either be a proximity of y to its previous value or of y*y to x.
With 385 as my x value I get these values in my iterations (Excel)
You can use an "approximate" 2^(log base 2(x)/2) as a start point instead of 1.
385 has a log somewhere between 8 and 9, so if we say 8.5 and therefore start with 2^4.25. If we do this linear between 16 and 32 then we would start with 20.
Starting with 20 I get there in just 4 steps:
but it required previous "iterations" to calculate the approximate log and exponential.