Exemple #1
0
/*
 * 作用:把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;
}
Exemple #2
0
int main()
{
	int i,b;
	ln sum=ln_init(1);
	ln k=NULL;
	ln temp=NULL;
	ln j=ln_init(1);
	i=2;
	b=7830457;
	j->lowestdigit->digit=i;
	j->highestdigit=j->lowestdigit;
	k=ln_init(i);
	b--;	
	while(1)
	{
		temp=copy_largenums(temp,j);
		multiply_largenums(j,temp,firstnumber);
		if(get_digitnum(j)>10)
			ln_truncate(j,3);
		b/=2;
		if(b==1)
			break;
		if(b%2!=0)
		{
			multiply_largenums(k,j,firstnumber);
			b--;
		}
	}
	free_largenum(temp);
	multiply_largenums(k,j,firstnumber);
	j=largenum_setval(j,28433);
	multiply_largenums(k,j,firstnumber);


	add_largenums(sum,k,firstnumber);

	show_largenum(sum);
	return 0;
}
Exemple #3
0
//get the numerator part of the num in base b and converted to base 10
ln get_numerator(const char* num,int b)
{
	const char*p;
	ln numerator;
	ln base;
	ln add_digit;
	numerator=ln_init(0);
	base=ln_init(1);
	p=num+strlen(num)-1;
	while(p>=num)
	{
		if(*p !='.')
		{
			add_digit=ln_multiply_int(base,*p-'0',newln);
			ln_add(numerator,add_digit,firstln);
			ln_free(&add_digit);
			ln_multiply_int(base,b,firstln);
		}
		p--;
	}
	return numerator;
}
Exemple #4
0
//get the denominator part of the num in base b and converted to base 10
ln get_denominator(const char* num,int b)
{
	const char*p;
	ln denominator;
	denominator=ln_init(1);
	p=strstr(num,".");
	if(p) //has fractional part
	{
		p++;
		while(*p)
		{
			ln_multiply_int(denominator,b,firstln);
			p++;
		}
	}
	return denominator;
}
Exemple #5
0
/*
 * 作用:比较ln a和int b的大小
 * 副作用:使用ln_stripleadingzero()把a整数部分前置0去掉
 * 参数:
 * 	a:待比较的ln
 * 	b:待比较的int
 * 返回值:
 * 	0: a=b
 * 	1: a>b
 * 	-1: a<b
 * 	-2: 出错
 */
int ln_cmp_int(ln a,int b)
{
	int res;
	ln c;
	//检查参数
	if(ln_checknull(a)!=0)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_checknull fail\n",__FILE__,__LINE__,__FUNCTION__);
		return -2;	
	}
	c=ln_init(b);
	if(c==NULL)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_init fail\n",__FILE__,__LINE__,__FUNCTION__);
		return -2;	
	}
	res=ln_cmp(a,c);
	ln_free(&c);
	return res;
}
Exemple #6
0
/*
 * 作用:把ln a加上int b
 * 副作用:调用ln_stripleadingzero()消除a前置0并且用ln_adjustpower()调整a的指数
 * 副作用:调用ln_stripleadingzero()消除结果的前置0
 * 参数:
 * 	a:待相加的ln
 * 	b:待相加的int
 *	restype:结果存放方式
 * 返回值:
 * 	成功:返回相加结果
 * 	失败:NULL
 */
ln ln_add_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;	
	}
	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_add(a,c,restype);
	ln_free(&c);
	return d;
}
int can_go(Pair* p){
  Pair *b = bts;
  Pair s, t, md, mv, mh, next, buf1, buf2, buf3;
  int v, h, ver, hor; /* coordinate steps */
  double val;
  int vis;
  
  while(b != bts+2){
    ln_init(b,p_get(Z,b)+0.5,p,p_get(Z,p)+0.5);
    /* go from the bottom up */
    if(p_get(Z,p) < p_get(Z,b)){
      s = *p;
      t = *b;
    }else{
      s = *b;
      t = *p;
    }
    
    hor = (s.c > t.c) ? -1 : 1;
    ver = (s.r > t.r) ? -1 : 1;
    
    #ifdef DEBUG
    printf("v: %d, h: %d\n",ver,hor);
    #endif
    
    h = (hor>0) ? 0 : 1;
    v = (ver>0) ? 0 : 1;
    
    vis = 1;
    while(!p_eq(&s,&t)){
      md = p_new(ver,hor);
      md = p_sum(&s,&md);
      buf1 = p_new(md.r+v,md.c+h);
      if(ln_rc_val(&buf1)==0){
        val = ln_z_by_r(buf1.r);
        next = md;  
      }else{
        mv = p_new(ver,0);
        mv = p_sum(&s,&mv);
        buf2 = p_new(mv.r+v,mv.c+h);
        if(!ln_rc_on_same_side(&buf1,&buf2)){
          val = ln_z_by_r(buf2.r);
          next = mv;    
        }else{
          mh = p_new(0,hor);
          mh = p_sum(&s,&mh);
          buf3 = p_new(mh.r+v,mh.c+h);
          val = ln_z_by_c(buf3.c);
          next = mh;
        }
      }
      #ifdef DEBUG
      printf("next %d,%d\n",next.r,next.c);
      #endif
      if(p_get(Z,&next) > val){
        
        #ifdef DEBUG
        printf("bad p: %d,%d val: %f\n",next.r,next.c,val);
        #endif
        
        vis = 0;
        break;
      }
      s = next;
    }
    if(vis) break;
    ++b; /* take next bts */
  }
  return vis;
}
Exemple #8
0
/*
 * 作用:把ln相除
 * 副作用:使用ln_stripleadingzero()把a,b整数部分前置0去掉
 * 参数:
 * 	a:除数
 * 	b:被除数
 *	precision:所需精度(保留的小数位数)
 *	mode:指定截断或者四舍五入
 *	restype:结果存放方式
 * 返回值:
 * 	成功:返回相加结果
 * 	失败:NULL
 */
ln ln_divide(ln a,ln b,int precision,divide_mode mode,res_type restype)
{
	ln c;
	ln x,y,z;
	int x_cellnum;
	int y_cellnum;
	int inc_prec=0; //累积精度
	cell i,j,k;

	//验证参数
	if(ln_checknull(a)!=0)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_checknull fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;	
	}
	if(ln_checknull(b)!=0)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_checknull fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;	
	}
	
	//去除前置0
	ln_stripleadingzero(a);
	ln_stripleadingzero(b);

	//复制ln
	x=ln_copy(NULL,a);
	if(x==NULL)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_copy fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;	
	}
	y=ln_copy(NULL,b);
	if(y==NULL)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_copy fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;	
	}
	//分配结果空间
	z=ln_init(0);
	if(z==NULL)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_init fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;	
	}

	//确定符号
	if(x->sign==y->sign)
		z->sign=1;
	else
		z->sign=-1;

	//把x,y整数部分节点数调整一致
	x_cellnum=ln_cellnum(x);
	if(x_cellnum==-1)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_cellnum fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;	
	}
	y_cellnum=ln_cellnum(y);
	if(y_cellnum==-1)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_cellnum fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;	
	}
	
	if(x_cellnum<y_cellnum)
		ln_adjustpower(x,(x_cellnum-y_cellnum)*DIGIT_NUM);
	if(y_cellnum<x_cellnum)
		ln_adjustpower(y,(y_cellnum-x_cellnum)*DIGIT_NUM);
	//算出初始精度
	inc_prec=ln_pointnum(x,x->lsd)-DIGIT_NUM+y->power;

	x->sign=1;
	x->power=0;
	y->power=0;
	z->power=0;
	i=x->msd;
	j=y->msd;
	k=z->msd;

	while(1)
	{
		if(i!=x->msd) 
			k->num=(i->num+i->hcell->num*UNIT)/j->num; //求出z位数
		else
			k->num=i->num/j->num; //求出z位数
		//printf("addr=%d num=%d\n",(int)k,k->num);
		if(k->num !=0)
		{
			y->sign=-1; //y变成负数
			c=ln_multiply_int(y,k->num,newln);
			ln_add(x,c,firstln);
			ln_free(&c);
			while(x->sign==1) //少减了,再减去
			{
				y->sign=-1;
				ln_add(x,y,firstln);
				k->num++;
			}
			while(x->sign==-1) //多减了,补上
			{
				y->sign=1;
				ln_add(x,y,firstln);
				k->num--;
			}
		}

		//开始计算当前精度
		inc_prec+=DIGIT_NUM;
		if(inc_prec>precision) //已经达到需要的精度
		{
			z->lsd=k;
			//确定指数
			z->power=-inc_prec;
			break;
		}
		

		if(ln_cmp_int(x,0)==0) //除得尽
		{
			z->lsd=k;
			//确定指数
			z->power=-inc_prec;
			break;
		}

		//去掉前置0
		if(x->msd->num==0 && x->msd !=x->lsd)
			x->msd=x->msd->lcell;

		//增加节点
		if(x->lsd->lcell ==x->msd)
		{
			if(ln_addcell(x,INIT_SIZE) ==NULL)
			{
				fprintf(stderr,"[%s %d] %s error,reason: ln_addcell fail\n",__FILE__,__LINE__,__FUNCTION__);
				return NULL;
			}
		}
		x->lsd=x->lsd->lcell;
		x->lsd->num=0;
		i=i->lcell;

		//增加节点
		if(k==z->lsd)
		{
			if(ln_addcell(z,INIT_SIZE) ==NULL)
			{
				fprintf(stderr,"[%s %d] %s error,reason: ln_addcell fail\n",__FILE__,__LINE__,__FUNCTION__);
				return NULL;
			}
		}
		z->lsd=z->msd->hcell;
		k=k->lcell;
	}

	//释放临时ln
	ln_free(&x);
	ln_free(&y);
	//去除前置0
	ln_stripleadingzero(z);
	//获取精度
	ln_fix(z,precision,mode);
	//复制给a
	if(restype==firstln)
	{
		ln_copy(a,z);
		ln_free(&z);
		return a;
	}
	else
		return z;
}
Exemple #9
0
/*
 * 作用:把ln a除以int b
 * 副作用:调用ln_stripleadingzero()消除a前置0并且用ln_adjustpower()调整a的指数
 * 副作用:调用ln_stripleadingzero()消除结果的前置0
 * 参数:
 * 	a:除数
 * 	b:被除数
 *	precision:所需精度(保留的小数位数)
 *	mode:指定截断或者四舍五入
 *	restype:结果存放方式
 * 返回值:
 * 	成功:返回相加结果
 * 	失败:NULL
 */
ln ln_divide_int(ln a,int b,int precision,divide_mode mode,res_type restype)
{
	//TODO:如果a或者b=MIN_INT 这边会溢出要转换成ln除法
	int res=0;
	int carry=0;
	int inc_prec=0; //累积精度
	ln c,d;
	cell x,z;

	//验证参数
	if(ln_checknull(a)!=0)
	{
		fprintf(stderr,"[%s %d] %s error,reason: ln_checknull fail\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;
	}

	//精度参数有误
	if(precision<0)
	{
		fprintf(stderr,"[%s %d] %s error,reason: precision error\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;
	}
	//除数不能为0
	if(b==0)
	{
		fprintf(stderr,"[%s %d] %s error,reason: b=0\n",__FILE__,__LINE__,__FUNCTION__);
		return NULL;
	}

	//除数必须在-200000-200000之间否则下面计算有可能溢出,因此必须把b转化成ln再操作
	//这个范围是根据INT_MAX/UNIT即2147483647/10000得出
	if(b>200000 || b<-200000)
	{
		d=ln_init(b);
		if(d==NULL)
		{
			fprintf(stderr,"[%s %d] %s error,reason: ln_init fail\n",__FILE__,__LINE__,__FUNCTION__);
			return NULL;
		}
		c=ln_divide(a,d,precision,mode,restype);
		if(c==NULL)
		{
			fprintf(stderr,"[%s %d] %s error,reason: ln_divide fail\n",__FILE__,__LINE__,__FUNCTION__);
			return NULL;
		}
		return c;
	}
	

	//去除前置0
	ln_stripleadingzero(a);

	//没指定商的精度 那就使用默认精度
	if(precision<0)
		precision=DIV_PREC;

	if(restype==newln)
	{
		c=ln_creat(ln_cellnum(a));
		if(c==NULL)
		{
			fprintf(stderr,"[%s %d] %s error,reason: ln_creat fail\n",__FILE__,__LINE__,__FUNCTION__);
			return NULL;
		}
		c->msd=c->lsd->lcell;
	}
	else
		c=a;

	//确定符号
	if(b>0)
		c->sign=a->sign;
	else
	{
		c->sign=-a->sign;
		b=-b;
	}

	//算出初始精度
	inc_prec=ln_pointnum(a,a->msd)-DIGIT_NUM;

	//开始计算
	carry=0;
	x=a->msd;
	z=c->msd;
	res=x->num;
	while(1)
	{
		res+=carry*UNIT;
		z->num=res/b;
		carry=res%b;
		//开始计算当前精度
		inc_prec+=DIGIT_NUM;
		if(inc_prec>precision) //已经达到需要的精度
		{
			c->lsd=z;
			//确定指数
			c->power=-inc_prec;
			break;
		}
		//必须这样标识,否则如果a和c一样,则下面会修改lsd
		if(x==a->lsd)
			x=NULL;
		if(x==NULL)
		{
			if(carry==0) //除得尽
			{
				c->lsd=z;
				//确定指数
				c->power=-inc_prec;
				break;
			}
			res=0;
		}
		else
		{
			x=x->lcell;
			res=x->num;
		}

		if(z==c->lsd) //增加节点
		{
			if(ln_addcell(c,INIT_SIZE) ==NULL)
			{
				fprintf(stderr,"[%s %d] %s error,reason: ln_addcell fail\n",__FILE__,__LINE__,__FUNCTION__);
				return NULL;
			}
			c->lsd=c->msd->hcell;
		}
		z=z->lcell;
	}

	//获取精度
	ln_fix(c,precision,mode);
	return c;
}