ln ln_exp_int(ln i,int b,res_type restype) { ln j=NULL,k=NULL; assert(b>=0); if(b==0) { if(restype==newln) return str2ln(NULL,"1"); else return ln_setval(i,1); } else if(b==1) { if(restype==newln) return copy_lns(NULL,i); else return i; } else if(b==2) { if(restype==newln) return ln_square(i,newln); else return ln_square(i,firstln); } else { j=copy_lns(NULL,i); if(b%2==0) k=init_ln(1); else { k=copy_lns(NULL,i); b--; } while(1) { ln_square(j,firstln); b/=2; if(b==1) break; if(b%2!=0) { ln_multiply(k,j,firstln); b--; } } ln_multiply(k,j,firstln); ln_free(j); if(restype==newln) return k; else { copy_lns(&i,k); ln_free(k); return i; } } }
ln ln_square(ln a,res_type restype) { ln b; cell i,j,k,l; int res; if(a->lsd==a->msd) { if(restype==newln) return ln_multiply(a,a,newln); else return ln_multiply(a,a,firstln); } b=ln_creat(ln_nodenum(a)*2); b->sign=1; b->power=a->power*2; i=a->lsd; j=b->lsd; do { k=i; l=j; if(i->num !=0) { do { if(i==k) res=i->num*k->num+l->num; else res=(i->num*k->num*2)+l->num; if(res>=UNIT) { l->num=res%UNIT; l->hcell->num+=res/UNIT; } else l->num=res; k=k->hcell; l=l->hcell; } while(k != a->msd->hcell); } i=i->hcell; j=j->hcell->hcell; } while(i != a->msd->hcell); b->msd=j->lcell; if(restype==newln) return b; else { copy_lns(&a,b); ln_free(b); return a; } }
/* * 作用:把ln a乘以int b * 副作用:调用ln_stripleadingzero()消除a前置0并且用ln_stripendingzero()调整a的指数 * 副作用:调用ln_stripleadingzero()消除结果的前置0 * 参数: * a:待相乘的ln * b:待相乘的int * restype:结果存放方式 * 返回值: * 成功:返回相加结果 * 失败:NULL */ ln ln_multiply_int(ln a,int b,res_type restype) { ln c,d; //验证参数 if(ln_checknull(a)!=0) { fprintf(stderr,"[%s %d] %s error,reason: ln_checknull fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } //去除前置0 ln_stripleadingzero(a); //简单地去掉后置0 ln_stripendingzero(a); //把int转换为ln c=ln_init(b); if(c==NULL) { fprintf(stderr,"[%s %d] %s error,reason: ln_init fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } //相乘 d=ln_multiply(a,c,restype); if(d==NULL) { fprintf(stderr,"[%s %d] %s error,reason: ln_multiply fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } ln_free(&c); return d; }
int main(int argc, const char *argv[]) { int n; for (n=1; n<0xffffffff; n++) { char s[16]; char d[16]; sprintf(s, "%d", n); ln_multiply(s, "2", d, 16); char ret = digitals_equal(s, d); if (ret == 0) continue; ln_multiply(s, "3", d, 16); ret = digitals_equal(s, d); if (ret == 0) continue; ln_multiply(s, "4", d, 16); ret = digitals_equal(s, d); if (ret == 0) continue; ln_multiply(s, "5", d, 16); ret = digitals_equal(s, d); if (ret == 0) continue; ln_multiply(s, "6", d, 16); ret = digitals_equal(s, d); if (ret == 0) continue; printf("%s\n", s); break; } return 0; }
//add the two numbers char* add_nums(const char* num1,const char* base1,const char* num2,const char* base2) { const char* base_str[2]; const char* num_str[2]; char *p,*q; int base_gcd; int i,test_res; int base[2]; ln numerator[3],denominator[3]; vector digits; //test bases base_str[0]=base1; base_str[1]=base2; for(i=0;i<2;i++) { base[i]=test_base(base_str[i]); if(base[i]==-1) { printf("Error: invalid base [%s]!\n",base_str[i]); return NULL; } else if(base[i]==-2) { printf("Error: base [%s] is out of range "MACRO2STR(MIN_BASE)"-"MACRO2STR(MAX_BASE)"!\n",base_str[i]); return NULL; } } //test numbers num_str[0]=num1; num_str[1]=num2; for(i=0;i<2;i++) { test_res=test_num(num_str[i],base[i]); if(test_res==0) { printf("Error: invalid number [%s],the number should match the regular expression [0-9]+(.[0-9]+)? !\n",num_str[i]); return NULL; } else if(test_res==2) { printf("Error: invalid number [%s] in base %d !\n",num_str[i],base[i]); return NULL; } } //convert the two numbers into fraction form for(i=0;i<2;i++) { denominator[i]=get_denominator(num_str[i],base[i]); numerator[i]=get_numerator(num_str[i],base[i]); } for(i=0;i<2;i++) { p=ln2str(numerator[i]); q=ln2str(denominator[i]); printf("operand in fraction:%s/%s\n",p,q); fflush(stdout); free(p); free(q); } //compute the fraction denominator[2]=ln_multiply(denominator[0],denominator[1],newln); numerator[0]=ln_multiply(numerator[0],denominator[1],firstln); numerator[1]=ln_multiply(numerator[1],denominator[0],firstln); numerator[2]=ln_add(numerator[0],numerator[1],newln); //free unused numbers for(i=0;i<2;i++) { ln_free(&(numerator[i])); ln_free(&(denominator[i])); } p=ln2str(numerator[2]); q=ln2str(denominator[2]); printf("result in fraction:%s/%s\n",p,q); //simplifying the result fraction base_gcd=gcd(base[0],base[1]); if(base_gcd !=1) { while(ln_divideable_num(numerator[2],base_gcd)==1 && ln_divideable_num(denominator[2],base_gcd)==1) { ln_divide_int(numerator[2],base_gcd,0,trunc_res,firstln); ln_divide_int(denominator[2],base_gcd,0,trunc_res,firstln); } } p=ln2str(numerator[2]); q=ln2str(denominator[2]); printf("result in fraction:%s/%s\n",p,q); fflush(stdout); if(strcmp(q,"1")==0) { free(q); q=(char*)malloc(strlen(p)+4); if(!q) { ln_free(&(numerator[2])); ln_free(&(denominator[2])); printf("Error: coverting fraction to decimal number failed at line %d",__LINE__); return NULL; } sprintf(q,"%s 10",p); free(p); return q; } free(p); free(q); digits=get_decimal_digit(numerator[2],denominator[2]); if(!digits) { ln_free(&(numerator[2])); ln_free(&(denominator[2])); printf("Error: coverting fraction to decimal number failed at line %d",__LINE__); return NULL; } p=get_decimalstr(digits,denominator[2]); if(!p) { ln_free(&(numerator[2])); ln_free(&(denominator[2])); free_digit(digits); printf("Error: coverting fraction to decimal number failed at line %d",__LINE__); return NULL; } return p; }
/* * get the decimal digits */ vector get_decimal_digit(const ln numerator,const ln denominator) { ln a,b,c; ln i,j,k,l,temp; int power; vector digits; digits=vect_create_pointer(); if(!digits) return NULL; a=ln_copy(NULL,numerator); b=ln_copy(NULL,denominator); //get the digits if(ln_cmp(a,b)<0) { vect_pushelm(digits,a); ln_free(&b); return digits; } //find out the maxpower power=1; c=ln_exp_int(b,power,newln); while(ln_cmp(c,a)<=0) { ln_free(c); power++; c=ln_exp_int(b,power,newln); } ln_free(c); power--; while(ln_cmp(a,b)>=0) { c=ln_exp_int(b,power,newln); //binary search i=ln_setval(NULL,0); //i=0 j=ln_add_num(b,-1,newln); //j=numerator-1 while(1) { k=ln_add(i,j,newln); //k=(i+j)/2 k=ln_divide_num(k,2,0,trunc,firstln); temp=ln_multiply(k,c,newln); if(ln_cmp(temp,a)>0) //k*c>a { ln_free(j); j=ln_add_num(k,-1,newln); //j=k-1 ln_free(k); ln_free(temp); } else if(ln_cmp(temp,a)==0) //k*c=a { ln_free(i); ln_free(j); ln_free(c); break; } else //k*c<a { l=ln_add_num(k,1,newln); ln_free(temp); temp=ln_multiply(l,c,newln); if(ln_cmp(temp,a)==0) //(k+1)*c=a { ln_copy(&k,l); ln_free(i); ln_free(j); ln_free(c); ln_free(l); break; } else if(ln_cmp(temp,a)>0) //(k+1)*c>a { ln_free(temp); temp=ln_multiply(k,c,newln); ln_free(i); ln_free(j); ln_free(l); ln_free(c); break; } else //(k+1) <a { ln_free(i); i=ln_add_num(k,2,newln); //i=k+2 ln_free(k); ln_free(temp); } } } vect_pushelm(digits,k); minus_lns(a,temp,firstln); ln_free(temp); power--; } vect_pushelm(digits,a); ln_free(b); return digits; }