1
0
Fork 0
Libraries for bc and dc.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
3.2 KiB

#!/usr/local/bin/bc -l funcs.bc cf.bc
### CF_MISC.BC - Miscellaneous functions separated from CF.BC
## CF Alteration ##
# Take the absolute value of all terms in pbv array cf__[]
# . WARNING: This irrevocably changes the array!
define cf_abs_terms(*cf__[]) {
auto i,t,changed;
.=check_cf_max_();
changed=0;
for(i=0;i<cf_max&&cf__[i];i++){
t=cf__[i];if(t<0){t=-t;changed=1}
cf__[i]=t
}
return changed;
}
# Take the absolute value, less 1, of all terms in pbv array cf__[]
# . WARNING: This irrevocably changes the array!
define cf_abs1_terms(*cf__[]) {
auto i,err;
.=check_cf_max_();
for(i=0;i<cf_max&&cf__[i];i++)
if(0==(cf__[i]=abs(cf__[i])-1)){err=1;break}
if(err){
print "abs1_cf error: invalid cf for this transformation. truncation occurred\n";
}
return err;
}
# Return the value of a CF as if all terms are positive
define cf_value_abs(cf__[]) {
auto cp[];
.=cf_copy(cp[],cf__[])+cf_abs_terms(cp[])
return cf_value(cp[])
}
# Return the value of a CF as if all terms are positive and reduced by 1
define cf_value_abs1(cf__[]) {
auto cp[];
.=cf_copy(cp[],cf__[])+cf_abs1_terms(cp[])
return cf_value(cp[])
}
# Convert x through the cfn and abs transformations
# . and return the value of the resultant CF
define cfn_flip_abs(x) {
auto cf[];
.=cfn_new(cf[],x)+cf_abs_terms(cf[])
return cf_value(cf[])
}
# Convert x through the cfn and abs1 transformations
# . and return the value of the resultant CF
define cfn_flip_abs1(x) {
auto cf[];
.=cfn_new(cf[],x)+cf_abs1_terms(cf[])
return cf_value(cf[])
}
## Binary RLE <--> CF conversion ##
# Minkowski Question Mark function - Inverse of Conway Box
# . Treat the fractional part of x as a CF and transform it into a
# . representation of alternating groups of bits in a binary number
define cf_question_mark(cf__[]) {
auto os,n,i,b,x,t,tmax,sign,c;
.=check_cf_max_();
tmax=A^scale
sign=1;if(cf__[0]<0)sign=-1
b=0;t=1
for(i=1;i<cf_max&&cf__[i]&&t<tmax;i++){
if((c=cf__[i]*sign)<0){
print "question_mark_cf: terms not absolute values. aborting\n"
return 0;
}
for(j=c;j&&t<tmax;j--){x+=b/t;t+=t}
b=!b
}
os=scale
if(t<tmax){
c=0;while(t>1){.=c++;t/=A}
scale=c
}
x=(cf__[0]+sign*x)/1;
scale=os
return upscale_rational(x);
}
# As above but only generates a CF as intermediary
define question_mark(x) { # returns ?(x)
auto cf[];
.=cf_new(cf[],x)
return cf_question_mark(cf[])
}
# Conway Box function - Inverse of Minkowski Question Mark
# . Transform the fractional part of x by making a CF from a run-length
# . encoding of the binary digits, and using that as the new fractional part
define cf_conway_box(*cf__[],x) { # cf__[] = [[_x_]]
auto os,f[],max,p,i,b,bb,n,j,ix,sign,which0;
os=scale;scale+=scale
x=upscale_rational(x)
max=A^os;p=1
sign=1;if(x<0){sign=-1;x=-x}
x-=(b=int(x));cf__[0]=sign*b
b=0
n=1;j=1
for(i=0;i<=cf_max&&i<scale;i++){
x+=x;bb=int(x)
if(bb==b){.=n++}else{cf__[j++]=sign*n;p*=1+n;n=1}
b=bb;x-=b
}
if(n){cf__[j++]=sign*n;p*=1+n}
i=j;while(!i).=i--;.=i++
scale=os
return cf_tidy_();
}
# As above but only generates a CF as intermediary
define conway_box(x) {
auto os,f[],cf[];
.=cf_conway_box(cf[],x)
return cf_value(cf[])
}