On Tue, Nov 06, 2012 at 04:57:20PM -0430, Andres Perera wrote:
On Tue, Nov 6, 2012 at 3:27 PM, Otto Moerbeek o...@drijf.net wrote:
Hi,
And here's a diff to repair ^, whcih now produces correct results for
things like
(dc)0.1 _1 ^p
or
(bc)0.1 ^ -1
The diff is against very current, so beware.
i've lightly tested it against gnu bc and it works
i do have 2 small comments below
Fair enough. New diff.
-Otto
Index: bcode.c
===
RCS file: /cvs/src/usr.bin/dc/bcode.c,v
retrieving revision 1.44
diff -u -p -r1.44 bcode.c
--- bcode.c 6 Nov 2012 16:00:05 - 1.44
+++ bcode.c 7 Nov 2012 06:45:52 -
@@ -257,6 +257,12 @@ init_bmachine(bool extended_registers)
(void)signal(SIGINT, sighandler);
}
+u_int
+bmachine_scale(void)
+{
+ return bmachine.scale;
+}
+
/* Reset the things needed before processing a (new) file */
void
reset_bmachine(struct source *src)
@@ -991,7 +997,7 @@ bsub(void)
}
void
-bmul_number(struct number *r, struct number *a, struct number *b)
+bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
{
BN_CTX *ctx;
@@ -1005,11 +1011,9 @@ bmul_number(struct number *r, struct num
bn_check(BN_mul(r-number, a-number, b-number, ctx));
BN_CTX_free(ctx);
- if (rscale bmachine.scale rscale ascale rscale bscale) {
- r-scale = rscale;
- normalize(r, max(bmachine.scale, max(ascale, bscale)));
- } else
- r-scale = rscale;
+ r-scale = rscale;
+ if (rscale bmachine.scale rscale ascale rscale bscale)
+ normalize(r, max(scale, max(ascale, bscale)));
}
static void
@@ -1029,7 +1033,7 @@ bmul(void)
}
r = new_number();
- bmul_number(r, a, b);
+ bmul_number(r, a, b, bmachine.scale);
push_number(r);
free_number(a);
@@ -1160,7 +1164,7 @@ bexp(void)
struct number *a, *p;
struct number *r;
boolneg;
- u_int scale;
+ u_int rscale;
p = pop_number();
if (p == NULL) {
@@ -1191,7 +1195,7 @@ bexp(void)
if (BN_is_negative(p-number)) {
neg = true;
negate(p);
- scale = bmachine.scale;
+ rscale = bmachine.scale;
} else {
/* Posix bc says min(a.scale * b, max(a.scale, scale) */
u_long b;
@@ -1199,30 +1203,37 @@ bexp(void)
b = BN_get_word(p-number);
m = max(a-scale, bmachine.scale);
- scale = a-scale * (u_int)b;
- if (scale m || (a-scale 0 (b == BN_MASK2 ||
+ rscale = a-scale * (u_int)b;
+ if (rscale m || (a-scale 0 (b == BN_MASK2 ||
b UINT_MAX)))
- scale = m;
+ rscale = m;
}
if (BN_is_zero(p-number)) {
r = new_number();
bn_check(BN_one(r-number));
- normalize(r, scale);
+ normalize(r, rscale);
} else {
+ u_int ascale, mscale;
+
+ ascale = a-scale;
while (!BN_is_bit_set(p-number, 0)) {
- bmul_number(a, a, a);
+ ascale *= 2;
+ bmul_number(a, a, a, ascale);
bn_check(BN_rshift1(p-number, p-number));
}
r = dup_number(a);
- normalize(r, scale);
bn_check(BN_rshift1(p-number, p-number));
+ mscale = ascale;
while (!BN_is_zero(p-number)) {
- bmul_number(a, a, a);
- if (BN_is_bit_set(p-number, 0))
- bmul_number(r, r, a);
+ ascale *= 2;
+ bmul_number(a, a, a, ascale);
+ if (BN_is_bit_set(p-number, 0)) {
+ mscale += ascale;
+ bmul_number(r, r, a, mscale);
+ }
bn_check(BN_rshift1(p-number, p-number));
}
@@ -1235,8 +1246,7 @@ bexp(void)
bn_check(BN_one(one));
ctx = BN_CTX_new();
bn_checkp(ctx);
- scale_number(one, r-scale + scale);
- normalize(r, scale);
+ scale_number(one, r-scale + rscale);
if (BN_is_zero(r-number))
warnx(divide by zero);
@@ -1245,8 +1255,9 @@ bexp(void)
r-number, ctx));
BN_free(one);
BN_CTX_free(ctx);
+ r-scale = rscale;
} else
-