[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
regression in bc(1) -> bug in dc
- To: tech_(_at_)_openbsd_(_dot_)_org
- Subject: regression in bc(1) -> bug in dc
- From: Paul de Weerd <weerd_(_at_)_weirdnet_(_dot_)_nl>
- Date: Tue, 30 Nov 2004 19:48:03 +0100
Hi all,
I noticed a regression in bc(1) over the previous (GNU) version when
calculating the square root from integers :
$ uname -a
OpenBSD wormhole 3.4 GENERIC#18 i386
$ echo 'sqrt(10)' | bc
3
$ uname -a
OpenBSD banana 3.6 BANANA#0 i386
$ echo 'sqrt(10)' | bc
2
Since our bc is now dc-based, this proves to be a bug in dc(1) :
$ dc
10
v
p
2
Not all square roots display this behaviour, but initial testing shows
quite a few (small) integers affected :
$ cat sqrts
for i in `jot 1000`
do
a=`echo "sqrt(${i})" | bc`
b=`echo "sqrt(${i})" | bc -l | cut -f1 -d'.'`
if [ ${a} -ne ${b} ] # this assumes bc -l is right
then
echo -n "${i} "
fi
done
$ sh sqrts
9 10 11 40 41 42 43 44 49 50 51 52 53 54 55 208 209 210 211 212 213 \
214 215 216 217 218 219 220 225 226 227 228 229 230 231 232 233 234 \
235 236 237 238 239 928 929 930 931 932 933 934 935 936 937 938 939 \
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 \
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 \
978 979 980 981 982 983 984 985 986 987 988 989 990 991
I've tried patching dc. Unfortunately, I couldn't really figure out
from the code if this was 'simply' some sort of off-by-one-bug or
a slight oversight. Therefor I have assumed the latter and patched
accordingly :
Index: bcode.c
===================================================================
RCS file: /cvs/src/usr.bin/dc/bcode.c,v
retrieving revision 1.22
diff -u -r1.22 bcode.c
--- bcode.c 11 Feb 2004 20:44:31 -0000 1.22
+++ bcode.c 30 Nov 2004 18:32:27 -0000
@@ -1255,7 +1255,7 @@
{
struct number *n;
struct number *r;
- BIGNUM *x, *y;
+ BIGNUM *x, *y, *z;
u_int scale;
BN_CTX *ctx;
@@ -1263,6 +1263,7 @@
if (n == NULL) {
return;
}
+ z = BN_dup(n->number);
if (BN_is_zero(n->number)) {
r = new_number();
push_number(r);
@@ -1285,6 +1286,15 @@
bn_check(BN_rshift1(x, x));
if (bsqrt_stop(x, y))
break;
+ }
+ if (n->scale == 0) {
+ BN_one(x);
+ bn_check(BN_add(x, x, y));
+ bn_check(BN_sqr(x, x, ctx));
+ if (BN_cmp(x, z) != 1) {
+ BN_one(x);
+ bn_check(BN_add(y, y, x));
+ }
}
r = bmalloc(sizeof(*r));
r->scale = scale;
This diff appears to solve the regression mentioned above :
$ sh sqrts
$
Any comments ?
Cheers,
Paul 'WEiRD' de Weerd
--
>++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+
+++++++++++>-]<.>++[<------------>-]<+.--------------.[-]
http://www.weirdnet.nl/
Visit your host, monkey.org