|
Packit Service |
f629e6 |
# Date: Sat, 02 Aug 2014 12:27:00 -0400
|
|
Packit Service |
f629e6 |
# To: bug-gawk@gnu.org
|
|
Packit Service |
f629e6 |
# From: Katherine Wasserman <katie@wass.net>
|
|
Packit Service |
f629e6 |
# Message-ID: <E1XDc9F-0007BX-O1@eggs.gnu.org>
|
|
Packit Service |
f629e6 |
# Subject: [bug-gawk] GAWK 4.1 SQRT() bug
|
|
Packit Service |
f629e6 |
#
|
|
Packit Service |
f629e6 |
# In version 4.1.60 of GAWK the sqrt() function does not work correctly on bignums.
|
|
Packit Service |
f629e6 |
# Here's a demo of the problem along with, a function that does work correctly.
|
|
Packit Service |
f629e6 |
#
|
|
Packit Service |
f629e6 |
# Running this program (sqrt-bug.awk):
|
|
Packit Service |
f629e6 |
# --------------------------------------------------------------------
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
@load "intdiv"
|
|
Packit Service |
f629e6 |
BEGIN {
|
|
Packit Service |
f629e6 |
a=11111111111111111111111111111111111111111111111111111111111
|
|
Packit Service |
f629e6 |
print sqrt(a^2)
|
|
Packit Service |
f629e6 |
#print sq_root(a^2)
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# ADR: Added for gawk-4.1-stable which doesn't have built-in intdiv() function
|
|
Packit Service |
f629e6 |
if (PROCINFO["version"] < "4.1.60")
|
|
Packit Service |
f629e6 |
print sq_root2(a^2)
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
print sq_root(a^2)
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
function sq_root(x, temp,r,z)
|
|
Packit Service |
f629e6 |
{ temp=substr(x,1,length(x)/2) + 0 # a good first guess
|
|
Packit Service |
f629e6 |
z=0
|
|
Packit Service |
f629e6 |
while (abs(z-temp)>1)
|
|
Packit Service |
f629e6 |
{ z=temp
|
|
Packit Service |
f629e6 |
intdiv(x,temp,r)
|
|
Packit Service |
f629e6 |
temp=r["quotient"] + temp
|
|
Packit Service |
f629e6 |
intdiv(temp,2,r)
|
|
Packit Service |
f629e6 |
temp=r["quotient"]
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
return temp
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
function sq_root2(x, temp,r,z)
|
|
Packit Service |
f629e6 |
{ temp=substr(x,1,length(x)/2) + 0 # a good first guess
|
|
Packit Service |
f629e6 |
z=0
|
|
Packit Service |
f629e6 |
while (abs(z-temp)>1)
|
|
Packit Service |
f629e6 |
{ z=temp
|
|
Packit Service |
f629e6 |
awk_div(x,temp,r)
|
|
Packit Service |
f629e6 |
temp=r["quotient"] + temp
|
|
Packit Service |
f629e6 |
awk_div(temp,2,r)
|
|
Packit Service |
f629e6 |
temp=r["quotient"]
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
return temp
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
function abs(x)
|
|
Packit Service |
f629e6 |
{ return (x<0 ? -x : x)
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#
|
|
Packit Service |
f629e6 |
# --------------------------------------------------------------------
|
|
Packit Service |
f629e6 |
# gawk -M -f sqrt-bug.awk
|
|
Packit Service |
f629e6 |
#
|
|
Packit Service |
f629e6 |
# results in:
|
|
Packit Service |
f629e6 |
# 11111111111111111261130863809439559987542611609749437808640
|
|
Packit Service |
f629e6 |
# 11111111111111111111111111111111111111111111111111111111111
|
|
Packit Service |
f629e6 |
#
|
|
Packit Service |
f629e6 |
# Thanks,
|
|
Packit Service |
f629e6 |
# Katie
|
|
Packit Service |
f629e6 |
#
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
# div --- do integer division
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
function awk_div(numerator, denominator, result, i, save_PREC)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
save_PREC = PREC
|
|
Packit Service |
f629e6 |
PREC = 400 # good enough for this test
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
split("", result)
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
numerator = int(numerator)
|
|
Packit Service |
f629e6 |
denominator = int(denominator)
|
|
Packit Service |
f629e6 |
result["quotient"] = int(numerator / denominator)
|
|
Packit Service |
f629e6 |
result["remainder"] = int(numerator % denominator)
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
PREC = save_PREC
|
|
Packit Service |
f629e6 |
return 0.0
|
|
Packit Service |
f629e6 |
}
|