前言
这是一个对有效数字较少的数字进行开平方运算的方法
某节物理课,和黄同学研究后得出
他提出方法我改进,提升精度
我感觉肯定已经有先人提出了这个估算法,但是这个方法毕竟是自己研究出来的也值得记录
方法
对数字$x$,首先进行要找到两个连续正整数$a_1a_2$使$a_1^2 \le x \le a_2^2$
由于一般学生背诵的平方数到$20^2$为止因此只能估算$[1,400]$范围的数字
①当x接近于$a_1^2$时
$$\sqrt{x}=a_1+\frac{x-a_1^2}{2a_1}$$
②当x接近于$a_2^2$时
$$\sqrt{x}=a_2-\frac{a_2^2-x}{2a_2}$$
其实两个式子是一个式子,为了便于计算略作调整使得所有中间结果均为正数
误差
误差检验代码
package main
import (
"fmt"
"math"
)
func main() {
var i, a, sqrtNum, exactNum float64
var deviation [40000]float64
var deviationTotal float64
for i = 1; i < 400; i = i + 0.01 {
a = findCloseSquare(i)
sqrtNum = a + (i-a*a)/2/a
exactNum = math.Sqrt(i)
deviation[int64(i*100)] = math.Abs(sqrtNum - exactNum)
}
var tmp int64
for tmp = 100; tmp < 40000; tmp++ {
//fmt.Println(float64(tmp)/100, ":", deviation[tmp])
deviationTotal += deviation[tmp]
}
fmt.Println(deviationTotal / 39900)
}
func findCloseSquare(i float64) float64 {
var a float64
for a = 1; a < 20; a = a + 1 {
if i < a*a {
if a*a-i < i-(a-1)*(a-1) {
return a
}
return a - 1
}
}
return a
}
PS D:\src\test\sqrttest> go run .\sqrt.go
0.004457902846500094
取4.00到399.99其间39600个数字时平均误差0.004457902846500094
一般地,可以较为精确地计算开平方的小数点后二位
其他优化技巧
- 对$x<4$的数字可以令$y=100x$再进行估算,最后再除以10
- 多背点平方数