1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
# Date: Sat, 02 Aug 2014 12:27:00 -0400
# To: bug-gawk@gnu.org
# From: Katherine Wasserman <katie@wass.net>
# Message-ID: <E1XDc9F-0007BX-O1@eggs.gnu.org>
# Subject: [bug-gawk] GAWK 4.1 SQRT() bug
#
# In version 4.1.60 of GAWK the sqrt() function does not work correctly on bignums.
# Here's a demo of the problem along with, a function that does work correctly.
#
# Running this program (sqrt-bug.awk):
# --------------------------------------------------------------------
@load "intdiv"
BEGIN {
a=11111111111111111111111111111111111111111111111111111111111
print sqrt(a^2)
#print sq_root(a^2)
# ADR: Added for gawk-4.1-stable which doesn't have built-in intdiv() function
if (PROCINFO["version"] < "4.1.60")
print sq_root2(a^2)
else
print sq_root(a^2)
}
function sq_root(x, temp,r,z)
{ temp=substr(x,1,length(x)/2) + 0 # a good first guess
z=0
while (abs(z-temp)>1)
{ z=temp
intdiv(x,temp,r)
temp=r["quotient"] + temp
intdiv(temp,2,r)
temp=r["quotient"]
}
return temp
}
function sq_root2(x, temp,r,z)
{ temp=substr(x,1,length(x)/2) + 0 # a good first guess
z=0
while (abs(z-temp)>1)
{ z=temp
awk_div(x,temp,r)
temp=r["quotient"] + temp
awk_div(temp,2,r)
temp=r["quotient"]
}
return temp
}
function abs(x)
{ return (x<0 ? -x : x)
}
#
# --------------------------------------------------------------------
# gawk -M -f sqrt-bug.awk
#
# results in:
# 11111111111111111261130863809439559987542611609749437808640
# 11111111111111111111111111111111111111111111111111111111111
#
# Thanks,
# Katie
#
# div --- do integer division
function awk_div(numerator, denominator, result, i, save_PREC)
{
save_PREC = PREC
PREC = 400 # good enough for this test
split("", result)
numerator = int(numerator)
denominator = int(denominator)
result["quotient"] = int(numerator / denominator)
result["remainder"] = int(numerator % denominator)
PREC = save_PREC
return 0.0
}
|