贡献者: addis; ChatGPT
1我们举例说明如何用长除法计算开根号
注意该算法适合手动计算,但并不适合用于在计算机中实际使用,计算机一般用效率更高的迭代法等。
若我们要算 $s^2$ 的开根号,并假设 $s$ 的 $n$ 位有效数字(不做四舍五入)为 $s_n$,例如 $s = \sqrt{2} = 1.414213562\dots$,则 $s_1 = 1$,$s_2=1.4$,$s_3=1.41$,……那么显然有
这里给出上面计算过程的 Matlab 代码 sqrt_hand.m
,若有例子不会算可以用它来教学。例如要计算图 1 中的例子 $\sqrt{21}$ 的 6 位小数,可以调用 sqrt_hand(21, 6)
,输出如下:
4.58257...
-----------------
4, 4, 21, 16
5, 85, 500, 425
8, 908, 7500, 7264
2, 9162, 23600, 18324
5, 91645, 527600, 458225
7, 916507, 6937500, 6415549
sqrt_hand(3, 6)
1.73205...
-----------------
1, 1, 3, 1
7, 27, 200, 189
3, 343, 1100, 1029
2, 3462, 7100, 6924
0, 34640, 17600, 0
5, 346405, 1760000, 1732025
sqrt_hand(0.3, 6)
(实际计算 $\sqrt{30}$)
0.54772...
-----------------
5, 5, 30, 25
4, 104, 500, 416
7, 1087, 8400, 7609
7, 10947, 79100, 76629
2, 109542, 247100, 219084
2, 1095442, 2801600, 2190884
sqrt_hand(8, 6)
2.82842...
-----------------
2, 2, 8, 4
8, 48, 400, 384
2, 562, 1600, 1124
8, 5648, 47600, 45184
4, 56564, 241600, 226256
2, 565682, 1534400, 1131364
sqrt_hand(110, 6)
(实际计算 $\sqrt{1.1}$)
10.4880...
-----------------
1, 1, 1.1, 1
0, 20, 10, 0
4, 204, 1000, 816
8, 2088, 18400, 16704
8, 20968, 169600, 167744
0, 209760, 185600, 0
function sqrt_hand(x, N)
if x <= 0
error('x <= 0');
end
if N > 14
error('too many digits!');
end
order = log10(x); % 0 to 2
scale = round((1-order)/2)*2;
ans_str = num2str(sqrt(x), N+2);
disp([ans_str(1:N+1) '...']);
x1 = x*10^scale;
d = zeros(1, N);
tmp = sqrt(x1);
% get digits (cheating)
for i = 1:N
d(i) = floor(tmp);
tmp = (tmp-d(i))*10;
end
rem = x1;
disp('-----------------');
left0 = 0;
for i = 1:N
left = left0*10 + d(i);
low = left*d(i);
disp(d(i) + ", " + left + ", " + rem + ", " + low);
rem = (rem - low)*100;
left0 = left0*10 + d(i)*2;
end
end