[comp.unix.wizards] Reliability of `bc'

ronald@atcmp.nl (Ronald Pikkert) (03/04/91)

From article <1991Mar1.093606.3280@glance.ch>, by david@glance.ch (David Mosberger):
] What may cause these strange results with control characters in the output?

I tried this input:

a=119615636279504466
b=196129796
a
b
a/b
scale=15
a/b

and it gave this ouput:

119615636279504466
196129796
609880-2208
609879981.109573305220793

I found that any scale >= 1 solves the problem. I'm not sure
about the exact cause.

-
Ronald Pikkert                 E-mail: ronald@atcmp.nl
@ AT Computing b.v.            Tel:    080 - 566880
Toernooiveld
6525 ED  Nijmegen

luuk@cs.vu.nl (Luuk Uljee) (03/05/91)

In article <1991Mar1.093606.3280@glance.ch>,
	david@glance.ch (David Mosberger) writes:
> A little test program to check a 64 bit division algorithm with `bc'
> unexpectedly turned into a test program for `bc' itself (after I found
> two bugs in my program :-).
> ..
> Does anybody know more about the reliability of `bc,' and what
> may cause these strange results with control characters in the output?


The following diff fixes this problem. It says nothing about the reliability
of bc/dc though.
The problem was caused by a miscalculation of the current high order digit of
the quotient. It could become one too high and thus the intermediate remainder
could get negative. Since this was unaccounted for, strange things resulted.
By printing digits that were out of range the minuses and the control chars
appeared. The original code only corrected for the digit being one too low.

(Warning: These diffs are t.o.v. SunOS 3.2 /usr/bin/dc.) 
------------------------------------------------------------------------------
*** dc.c	Mon Mar  4 13:08:11 1991
--- bdc.c	Mon Mar  4 18:51:48 1991
***************
*** 655,672 ****
  			}
  			salterc(divd,d);
  		}
! 		divcarry = carry;
  		sbackc(p);
  		salterc(p,dig);
  		sbackc(p);
  		if(--offset >= 0)divd->wt--;
- 	}
- 	if(divcarry != 0){
- 		salterc(p,dig-1);
- 		salterc(divd,-1);
- 		ps = add(divr,divd);
- 		release(divd);
- 		divd = ps;
  	}
  
  	rewind(p);
--- 655,677 ----
  			}
  			salterc(divd,d);
  		}
! 		if(carry){
! 			rewind(divr);
! 			seekc(divd,offset);
! 			dig --;
! 			carry=0;
! 			while(sfeof(divr) == 0){
! 				d = sgetc(divr)+sgetc(divd)+carry;
! 				carry = d / 100;
! 				sbackc(divd);
! 				salterc(divd,d%100);
! 			}
! 		}
! 
  		sbackc(p);
  		salterc(p,dig);
  		sbackc(p);
  		if(--offset >= 0)divd->wt--;
  	}
  
  	rewind(p);
-------------------------------------------------------------------------------
Luuk (luuk@cs.vu.nl).