On Mon, 29 Jan 2007, Otto Moerbeek wrote:
> On Mon, 29 Jan 2007, Otto Moerbeek wrote:
>
> > On Mon, 29 Jan 2007, Karel Kulhavy wrote:
> >
> > > I just found three bugs in the OpenBSD 4.0 "bc" program.
> >
> >
> > All three bugs seem to related to the use of a non-decimal input base
> > in combination with using the -l lib.
> >
> > This is because the stored routines interpret the number according to
> > the base at execution time.
> > Shows what is going on. I have to think a bit on how to solve it and
> > what (id) SU says anything about this.
> >
> > $ bc
> > define d(x) {
> > return x + 1.1;
> > }
> > d(0)
> > 1.1
> > ibase=2
> > d(0)
> > 1.5
>
> SU does not say anthing explicit about this on first read. In the
> meantime I checked Solaris and the original AT&T bc/dc. They both
> produce the same results as above. So the behaviour might be
> surprising, but it is historically consistent.
>
> Strange is that your 0) test does work OK on Solaris. Some more
> investigation to be done...
It turns out the -l functions in Solaris save/restore the input base.
The diff below fixes it for l(). Note that some of your tests still
produce strange results, but that is due to weird handling of
non-decimal fractions wrt scale:
For example, with ibase=11
0.1 produces 0.0
0.10 produces .09
0.100 produces 0.090
As far as I remember, this is consistent behaviour compared to
historic versions of bc.
-Otto
Index: bc.library
===================================================================
RCS file: /cvs/src/usr.bin/bc/bc.library,v
retrieving revision 1.1
diff -u -p -r1.1 bc.library
--- bc.library 25 Sep 2003 19:34:22 -0000 1.1
+++ bc.library 29 Jan 2007 09:36:41 -0000
@@ -80,8 +80,14 @@ define e(x){
}
define l(x){
- auto a, b, c, d, e, f, g, u, s, t
- if(x <=0) return(1-10^scale)
+ auto a, b, c, d, e, f, g, u, s, t, r
+ r = ibase;
+ ibase = A;
+ if(x <= 0) {
+ a = 1-10^scale;
+ ibase = r;
+ return(a)
+ }
t = scale
f=1
@@ -116,6 +122,7 @@ define l(x){
g=c/d
if(g==e){
scale = t
+ ibase = r;
return(u*c/d)
}
e=g