On Sat, Nov 03, 2012 at 11:49:30AM -0700, [email protected] wrote:
> 0^-1 divides by zero, shows random bn warning and kills dc. doesn't
> happen with other div operators
A divide by zero happens, diff below catches it. Posix only talks
about the scale of the end result, not of intermediate results. Have
to thing a bit.
>
> also, requesting something like this just to workaround a warning
> is counter productive, especially when you need a fraction during
> an expression that involves exponentiation
Dunno, gnu bc/dc also warn in this case, and I think it is a useful warning.
-Otto
Index: bcode.c
===================================================================
RCS file: /cvs/src/usr.bin/dc/bcode.c,v
retrieving revision 1.42
diff -u -p -r1.42 bcode.c
--- bcode.c 8 Mar 2012 08:15:37 -0000 1.42
+++ bcode.c 3 Nov 2012 20:26:15 -0000
@@ -1230,7 +1230,12 @@ bexp(void)
bn_checkp(ctx);
scale_number(one, r->scale + scale);
normalize(r, scale);
- bn_check(BN_div(r->number, NULL, one, r->number, ctx));
+
+ if (BN_is_zero(r->number))
+ warnx("divide by zero");
+ else
+ bn_check(BN_div(r->number, NULL, one,
+ r->number, ctx));
BN_free(one);
BN_CTX_free(ctx);
} else
>
> ...
> s = scale
> scale = 0
> t = x / 1 /* round -Inf and get rid of scale to avoid
> superflous warning */
> scale = s
> ...
> y = (exp possibly containing division with fractions to keep) + z^t
>
>
>
> Index: bcode.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/dc/bcode.c,v
> retrieving revision 1.42
> diff -u -r1.42 bcode.c
> --- bcode.c 8 Mar 2012 08:15:37 -0000 1.42
> +++ bcode.c 3 Nov 2012 18:39:11 -0000
> @@ -1176,12 +1176,17 @@
> return;
> }
>
> - if (p->scale != 0)
> - warnx("Runtime warning: non-zero scale in exponent");
> normalize(p, 0);
>
> neg = false;
> - if (BN_cmp(p->number, &zero) < 0) {
> + if (BN_is_negative(p->number)) {
> + if (BN_is_zero(a->number)) {
> + warnx("divide by zero");
> + r = new_number();
> + r->scale = bmachine.scale;
> + push_number(r);
> + return;
> + }
> neg = true;
> negate(p);
> scale = bmachine.scale;