手算平方根的JavaScript实现
Posted hans774882968
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手算平方根的JavaScript实现相关的知识,希望对你有一定的参考价值。
今天偶然了解到了一种手算平方根的方法。其流程如下:
- 用二分查找确定整数部分。若发现是完全平方数,则直接返回。
- 设之前已求出的整数部分和小数部分一起,不断乘10直到它是一个整数,为a,比如:之前已经求出11.45,那么a=1145。设要求的下一位是b,则:根据
100 * v = (10a+b)^2 = 100*a*a+20*a*b+b*b
(实际上这个公式就是手算法的原理,v
为待求根号的数,v = a + 0.1*b
)有: - 设上一轮得到的差值为
delta
,则初始的delta = v - intPart * intPart
,intPart
为整数部分。用本轮的a和b表示,则delta = 100*v-100*a*a = (10a+b)^2-100*a*a
,所以我们只需要求出最大的b,使得delta >= 20*a*b+b*b
。在此为了实现简单,直接遍历0~9了。
它相比于牛顿迭代等没有计算速度上的优势,牛顿迭代在此问题是平方收敛,它的速度就慢太多了。但如果只使用通常的double,牛顿迭代无法获得极其高的精度(比如小数点后114514位)。而这个手算的算法在使用BigInt的情况下可以达到任意精度。
代码
"use strict";
//node 开根号.js
//若v是完全平方数,则返回整数,否则返回want位小数
function mySqrt(v,want) {
let l = 1, r = v
while (l < r - 1) {
let mid = (l + r) >> 1
if (mid * mid > v) r = mid - 1
else l = mid
}
const intPart = r * r <= v ? r : l
let delta = v - intPart * intPart
if (!delta) return intPart
let tmp = intPart
let ans = []
for (let i = 1; i <= want; ++i) {
let val = 9
for (let j = 0; j < 10; ++j) {
if (20 * tmp * j + j * j > 100 * delta) {
val = j - 1
break
}
}
ans.push(val)
delta = 100 * delta - (20 * tmp * val + val * val)
tmp = 10 * tmp + val
// console.log(delta, tmp)//因为tmp会越来越大,所以delta大体上也会越来越大
}
return `${intPart}.${ans.join('')}`
}
//1.4142135623730 41 1.7320508075688 5.0990195135927
//2.2360679774997 2.4494897427831 2.6457513110645 338.3991725758
console.log(mySqrt(2,13))
console.log(mySqrt(1681,13))
console.log(mySqrt(3,13))
console.log(mySqrt(26,13))
console.log(mySqrt(5,13))
console.log(mySqrt(6,13))
console.log(mySqrt(7,13))
console.log(mySqrt(114514,10))
以上是关于手算平方根的JavaScript实现的主要内容,如果未能解决你的问题,请参考以下文章
html PHP代码片段: - AJAX基本示例:此代码演示了使用PHP和JavaScript实现的基本AJAX功能。