前言

这是一个对有效数字较少的数字进行开平方运算的方法

某节物理课,和黄同学研究后得出

他提出方法我改进,提升精度

我感觉肯定已经有先人提出了这个估算法,但是这个方法毕竟是自己研究出来的也值得记录

方法

对数字$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
  • 多背点平方数