On Tue, Nov 6, 2012 at 3:27 PM, Otto Moerbeek <[email protected]> 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

>
> Please test. I have some regress test updates for dc as well. t9 turns
> out to be a wrong test (computation of 2.1 ^ 500). That is fixed with
> this diff as well.
>
>         -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 -0000       1.44
> +++ bcode.c     6 Nov 2012 19:42:07 -0000
> @@ -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;
>
> @@ -1007,7 +1013,7 @@ bmul_number(struct number *r, struct num
>
>         if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) {
>                 r->scale = rscale;
> -               normalize(r, max(bmachine.scale, max(ascale, bscale)));
> +               normalize(r, max(scale, max(ascale, bscale)));
>         } else
>                 r->scale = rscale;

the function unconditionally sets r->scale to rscale, but the
operation is duplicated across `if' bodies. interpreting a diff for
the function is difficult because the intent is unclear

>  }
> @@ -1029,7 +1035,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 +1166,7 @@ bexp(void)
>         struct number   *a, *p;
>         struct number   *r;
>         bool            neg;
> -       u_int           scale;
> +       u_int           rscale;
>
>         p = pop_number();
>         if (p == NULL) {
> @@ -1191,7 +1197,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 +1205,35 @@ 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 scale, ascale = a->scale;

`scale' should be renamed for clarity to signify that it's an
accumulator for `ascale'. at its current state, not being prefixed by
a letter that is, `scale' looks more important than it is

Reply via email to