高精度幂的计算

题目参考北大onlie judge 1001题,由于不知道对于整数的相关输入要求,如果输入整数进入高精度幂的运算的话,默认为6.0000 or 12.000 格式。

/*对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。(限时0.5s) 

 *高精度幂的计算 
 */ 
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /*malloc automatic distribute */ 
#define LEN 11     /*考虑到换行符的影响 */
#define FLOAT_LEN 6
#define POWER_LEN 2
#define MAX_LEN 250 /*计算结果最大占用长度 */
/* 采用 链表,少占用内存 */ 
typedef struct data
{
char object[LEN];
char power[LEN];
int index_dot; 
int extra_zero; 
struct data *next;
}DATA,*DATA_P;


#define SIZE (sizeof(DATA))


char global_outcome[MAX_LEN]; /*用于存放每一个结构体运算的结果() */


int global_count; /*用于定位global_outcome在执行加和时最远点(为了reverse考虑)*/ 


int find_dot(char *);/*小数点index寻找函数 */


void release_stack(DATA_P); /*空间释放函数 */ 


void per_outcome_print(int,int,int);/*打印每一组数据运算的结果*/ 


void calculate(DATA_P); /*计算函数*/


void reverse(); /*调整global_outcome的字符顺序(一次计算过后,数值是反序存储的)*/ 


void add_help(char *,int); /* 辅助计算加和函数 */ 


int main(void)
{
DATA_P head,first;
first=(DATA_P)malloc(SIZE);
head=first;
head->next=NULL;

char *temp; /* 临时用于接收每一行输入的字符 */ 
temp=(char *)malloc(LEN*sizeof(char));
int count=0;
while(fgets(temp,LEN,stdin)!=NULL && *temp!='\n' && (++count))
{
head->index_dot=find_dot(temp);
head->extra_zero=0;
while(*(temp+FLOAT_LEN-1-head->extra_zero)=='0')
(head->extra_zero)++; 
strncpy(head->object,temp,(head->index_dot));
*((head->object)+(head->index_dot))='\0';
if(*(temp+FLOAT_LEN-1-head->extra_zero)!='.')
{
strncat(head->object,temp+(head->index_dot)+1,FLOAT_LEN-(head->index_dot)-1-head->extra_zero);
*((head->object)+FLOAT_LEN)='\0';
}

strncpy(head->power,temp+FLOAT_LEN+1,POWER_LEN);
*((head->power)+POWER_LEN)='\0';
head->next=(DATA_P)malloc(SIZE);
head=head->next;
head->next=NULL;  /*初始化为空指针 */
}

free(temp);/*释放临时存储字符数组 */
free(head);/*释放多余的一个结构体 */
  int i;
  head=first;
  for(i=0;i<count;i++)
  {
  strcpy(global_outcome,head->object);
calculate(head);
head=head->next;
memset(global_outcome,0,sizeof(global_outcome));
}
release_stack(first);

return 0;
}


void calculate(DATA_P point)
{
int cycle_number=atoi(point->power)-1;
int i,j,k;
int position=0;/*position值代表应该从第几位开始加 */
int t=0;/*作为swap index递增的指标 */
int mode_up; /*进位值 */
char *swap;/*中间字符数组,为了便于加和 */
swap=(char *)malloc(MAX_LEN*sizeof(char));
static char swap_copy[MAX_LEN];
global_count=4; 
for(i=1;i<=cycle_number;i++) 
{
if(i!=1)
reverse(); 
strncpy(swap_copy,global_outcome,global_count+1);
memset(global_outcome,'0',sizeof(global_outcome));/*将global_outcome 所有元素初始化为'0' */
memset(swap,0,MAX_LEN*sizeof(char));
global_count=position=0;
for(j=strlen(swap_copy)-1;j>=0;j--)
{
mode_up=0;
t=0;
for(k=strlen(point->object)-1;k>=0;k--)
{
*(swap+(t++))=(((*(swap_copy+j)-'0')*(*((point->object)+k)-'0')+mode_up)%10)+'0';
mode_up=((*(swap_copy+j)-'0')*(*((point->object)+k)-'0')+mode_up)/10;
}
if(mode_up>0)
*(swap+t)=mode_up+'0';
add_help(swap,position++);
memset(swap,0,MAX_LEN*sizeof(char));
}
}
free(swap);
per_outcome_print(point->index_dot,cycle_number+1,point->extra_zero);
memset(swap_copy,0,MAX_LEN*sizeof(char));
}


void add_help(char *swap,int position)
{
int i=0;
int mode_up=0;
int temp;
while(*swap++)
{
temp=((*(swap-1)+*(global_outcome+i+position)-'0'-'0')+mode_up)/10;
*(global_outcome+i+position)=(((*(swap-1)+*(global_outcome+i+position)-'0'-'0')+mode_up)%10)+'0';
mode_up=temp;
i++;
}
if(mode_up>0)
*(global_outcome+(i++)+position)=mode_up+'0';
global_count=i-1+position; /*index标准索引标值 */
}


int find_dot(char *object)/*寻找float数据的小数点所在index */
{
int index=0;
while((*object!=' ') && (*object++!='.'))
index++;
return index;
}


void per_outcome_print(int index_dot,int power,int extra_zero) /*打印结果(处理0.情况) */
{
int i;
if(index_dot+1+extra_zero!=FLOAT_LEN)
{
int dot_bit_number=(FLOAT_LEN-index_dot-1-extra_zero)*power;/*结果应该是多少位小数 */
for(i=global_count;i>=0;i--)
{
if(i==global_count && *(global_outcome+i)=='0')/* solve 0. situation */ 
continue;
if(i==dot_bit_number-1)
putchar('.');
putchar(*(global_outcome+i));
}
}
else
{
for(i=global_count;i>=0;i--)
putchar(*(global_outcome+i));
}
putchar('\n');



void release_stack(DATA_P first) /*释放所有动态分配的空间 */ 
{
DATA_P head,temp;
head=first;
while(head->next)
{
temp=head;
head=head->next;
free(temp);
}
}


void reverse()   /*global_outcome运算结果的正序化(最后一次计算直接反序输出) */
{
char *p_start=global_outcome;
char *p_end=global_outcome+global_count;
char temp;
while(p_start<p_end)
{
temp=*p_start;
*p_start++=*p_end;
*p_end--=temp;
}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值