On Sun, Nov 04, 2012 at 03:06:14PM -0430, Andres Perera wrote:

> On Sun, Nov 4, 2012 at 1:41 PM, Otto Moerbeek <[email protected]> wrote:
> >
> > It's easy to create a trunc function. Yes it will needs scale setting
> > en resetting, but I do not see that as a problem.
> >
> > On the other hand, being reminded that ^ does not do fractional exponents
> > is very important.
> 
> is it important because there is no root operator or because scale
> itself is a side effect in other currently present operators?
> 
> if it's the first, what about a patch that checks (scale &&
> fractional_part != 0) before issuing the warning?

Like teh diff below.

BTW I was looking into the case 0.1^-1. Single Unix is pretty
confusing about it, talking about an absolute value being negaitive.

To quote:

expression^expression

The result shall be the first expression raised to the power of the
second expression. If the second expression is not an integer, the
behavior is undefined. If a is the scale of the left expression and b
is the absolute value of the right expression, the scale of the result
shall be:
if b >= 0 min(a * b, max(scale, a)) if b < 0 scale


        -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     5 Nov 2012 19:35:41 -0000
@@ -1176,12 +1176,23 @@ bexp(void)
                return;
        }
 
-       if (p->scale != 0)
-               warnx("Runtime warning: non-zero scale in exponent");
+       if (p->scale != 0) {
+               BIGNUM *i, *f;
+               i = BN_new();
+               bn_checkp(i);
+               f = BN_new();
+               bn_checkp(f);
+               split_number(p, i, f);
+               if (!BN_is_zero(f))
+                       warnx("Runtime warning: non-zero fractional part in 
exponent");
+               BN_free(i);
+               BN_free(f);
+       }
+
        normalize(p, 0);
 
        neg = false;
-       if (BN_cmp(p->number, &zero) < 0) {
+       if (BN_is_negative(p->number)) {
                neg = true;
                negate(p);
                scale = bmachine.scale;
@@ -1230,7 +1241,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

Reply via email to