怎样表示超出long double 能表示的数?

时间:2008-05-10 20:51:54   来源:论坛整理  作者:  编辑:chinaitzhe
long double 能表示的数是10的308次方,我想知道超出这个范围的数怎样来表示出来。
网友回复:自己定义数据类型
网友回复:听别人说过似乎可以用数组存储

具体没试过
网友回复:数组
网友回复:看你怎么用了,大数相加用栈
网友回复:
引用 1 楼 laolaoliu2002 的回复:
自己定义数据类型


-?,举例?
网友回复:任何一个数都可以表示成指数形式,如下所示: N=nEe (0= <n的绝对值 <=1,e为10的指数幂)
例如100可以表示成1E2,1001可以表示成1.01E3
网友回复:采取用链表存贮的方式来存放大数。在计算中会用到从高位开始计算,和从低位开始计算数值的两种情况。所以我们将链表定义为双向链表,其中为一个单元来存贮数据,一个指针指向前方的数据,另一个指向后的数据。其结构为:
struct Node // 定义一个双向链表用来存贮结果
{
char data; // 数据*定义为字符的原因:要显示负号
Node *next; // 尾指针
Node *ahead; // 首指针
};
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/





/*--------------------------------------------------------------------------

*函数名称: 大数加法

*函数过程:1 比较两个数那一个长

* 2 以长的作为循环次数

* 3 对应项相加 进位存贮直到下高位相加用

* 4 直到循环结束

* 5 !!!!!!没设计负数相加

*入口参数:numa,numb,result字符串

*出口参数:无

*编辑环境:winSP2   VC2003   C  

*--------------------------------------------------------------------------*/

void addition(char *numa, char *numb,char *result) // 计算两大数之和

{

  char *pna = findend(numa); // 指向numa的一个指针。point numa pna 指向乘数的最低位,

  char *pnb = findend(numb); //指向numb的一个指针 //pnb 指向被乘数的最低位,

  int along=(int)strlen(numa); //标记数字a的长度;

  int blong=(int)strlen(numb); //标记数字b的长度;

  int times = 0; // 标致要计算多少次。

  int carry=0,temp_result; //存贮进位 和临时结果的

  Node *head, // 用于存贮头指针

    *pstart, // 用于存贮计算时的首指针

    *pnew; //作于申请新结点 

  head = pstart =new Node; //初始化首结点和头结点。

  pstart -> data = 0;

  pstart -> next = NULL;

  pstart -> ahead = NULL; 



  if (abigerb(numa ,numb)>=1)

  times = (int)strlen(numa); //比较两个字符串长度,以大的作为循环次数

  else

    {

      times = (int)strlen(numb);

      pna = findend(numb); //交换指针

      pnb = findend(numa);

    along=(int)strlen(numb); //标记数字a的长度;

    blong=(int)strlen(numa); //标记数字b的长度;

    }

    while ((times-- && (times>=0))|| carry != 0)

    { 

      if(!pstart->next) //假如当前为空结点,则申请新结点

      {

        pnew = new Node;

        pnew -> data = 0;

        pnew -> next = NULL;

        pnew -> ahead = pstart;

        pstart -> next = pnew;

      }

      else temp_result =(pstart->data  (*pna-48) (*pnb-48) carry) ; //自身的值 新值 进位 作为当前的新值



      pstart -> data = temp_result; //存贮个位

      carry = temp_result/10; //存贮进位

      pstart = pstart -> next; //结点移动

    blong--;

      if(blong>0)pnb--; //指针移向被加数高位

      else *pnb=48; //之后相减就变为了0不作任何运算;

      pna--; //加数指针移动,

    }

  pstart =head; //寻找链表的结尾点

  while(pstart->next != 0)

  {

  pstart->data  = 48; //!!<<<因为我们的输出是字符。所以再此加上48>>>> 逆顺输出

  pstart = pstart->next ;

  }



  int tip = 0; //转为字符串用

    pstart = pstart->ahead ; //找有效字

     //cout<<"\n结果是 : ";

    while(pstart != 0) //输出正序的结果;

    {

    result[tip  ] = pstart->data; 

     //cout<data;

    pstart = pstart->ahead ;

    }

    result[tip] = '\0';



  pstart =head; //释放空间

  while(pstart->next != 0)

  {

  pnew = pstart->next ;delete pstart;

  pstart =pnew; 

  }

  return ;

}




网友回复:/*--------------------------------------------------------------------------
*函数名称: 大数减法
*函数过程:1 比较两个数那一个长
* 2 以长的作为循环次数
* 3 假如两个数长度相等,从最高位开始比直到发现那一个数更大,使大项减去小项
* 4 对应项相减 进位存贮直到下高位相加用
* 5 每一位对应项相减时,处理三种可能的情况,a=b,ab;
* 6 a=b时,则计算,11-12,111-112,要考虑借位
* 7 直到循环结束
*入口参数:numa,numb,result字符串
*出口参数:无
*--------------------------------------------------------------------------*/

void subtract(char *numa, char *numb,char *result)//计算减
{
char *pna = findend(numa);//指向numa的一个指针。point numa pna 指向减数的最低位,
char *pnb = findend(numb);//指向numb的一个指针 //pnb 指向被减数的最低位,
int along=(int)strlen(numa);//标记数字a的长度;
int blong=(int)strlen(numb);//标记数字b的长度;
int times = 0; // 标记要计算多少次。
int carry=0; //存贮借位
int clear0=0; //消除结果最前面无用的'0' 13-5 = 08 的效果!!
int isnegative=0; //用来加上被减数大于减数时补上最后一个负号
Node *head, // 用于存贮头指针
*pstart, // 用于存贮计算时的首指针
*pnew; //作于申请新结点

head = pstart =new Node;//初始化首结点和头结点。
pstart -> data = 0;
pstart -> next = NULL;
pstart -> ahead = NULL;

if (abigerb(numa ,numb))
times = strlen(numa);//比较两个字符串长度,以大的作为循环次数
else //交换位置以降低难度
{
times = strlen(numb);//让数(字符串)长的减去数(字符串)短的
pna = findend(numb);//交换指针
pnb = findend(numa);
along=(int)strlen(numb);//标记数字a的长度;
blong=(int)strlen(numa);//标记数字b的长度;
isnegative=1;//标记最后要加上负号
}
while ((times-- && (times>=0)) ¦ ¦ carry != 0)//carry != 0 说没有借位时
{
if(!pstart->next)//假如当前为空结点,则申请新结点
{
pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew;
}
if(times <0)//假如计算完之后,借位等于1,,说明必然为负值;
{
pstart -> data = -3 ;//让它等于负号 '-'//-3来源于负号与0相差3。。 break;
}
else
{
if ( *pna == *pnb )//减数等于被减数时。结果等于直截相减的结果;并置借位为0
{
if(carry==0)pstart -> data = (*pna-48)-(*pnb-48); //111-11的情况
else
{
pstart->data = (*pna-48)-(*pnb-48) 10 -carry;//1121-1112
carry=1;
}
}
if( *pna > *pnb )//减数大于被减数时。结果等于直截相减的结果;并置借位为0
{
pstart -> data = (*pna-48)-(*pnb-48)-carry; //存贮个位
carry=0;
}
else if( *pna < *pnb )//说明被减数大于减数,让结果加10,相当于借位 (carry)为1
{
if(times>0) pstart->data = (*pna-48)-(*pnb-48) 10 -carry;//13-5的情况作为新值
else pstart->data = (*pnb-48)-(*pna-48) -carry; //3-5 作为当前的新值
carry=1;
}
}
pstart = pstart -> next; //结点移动

blong--;
if(blong>0)pnb--;//指针移向被减数高位
else *pnb=48;//之后相减就变为了0不作任何运算,其实可以优化的。但代码会长!而且还需要重新开结点。所以放弃;
pna--;//被数指针移动,
}
if(isnegative==1)////加上负号处理。增加一长度并置为负号
{
pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew;
pstart->data=-3;//因为寻找链表的结尾点要统一加48。又因为‘-’是45。所以等于‘-3’
}

pstart =head;//寻找链表的结尾点
while(pstart->next != 0)
{
pstart->data = 48;//!! < < <因为我们的输出是字符。所以再此加上48>>>> 逆顺输出
pstart = pstart->next ;
}

int tip = 0;//转为字符串用
clear0=0;// 消除结果最前面无用的'0' 13-5 = 08 的效果 ..>>修改字符串的首指针
pstart = pstart->ahead ;//找有效字
while(pstart != 0)//输出正序的结果;
{
if (clear0==0 && ((int)pstart->data)==48&&pstart->ahead!=0)// 消除结果最前面无用的'0'
;//不输出任何东西
else
result[tip ] = pstart->data;

if(((int)pstart->data)!=48&&((int)pstart->data)!=45)clear0=1;//'-'号
pstart = pstart->ahead ;
}
result[tip] = '\0';

pstart =head; //释放空间
while(pstart->next != 0)
{
pnew = pstart->next ;delete pstart;
pstart =pnew;
}
return ;
}


网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/





/*--------------------------------------------------------------------------

*函数名称: 大数乘法

*函数过程:1 输入两个大数作为字符串

* 2 作一个双向链表

* 3 两个指针分别指向数字字符串的最低位

* 4 以第一个数的最低的一个位乘以第二个数的所有项存于链表中

* 5 链表首指针移

* 6 重复4,5依次从最低位乘到最高位

* 7 乘完后因为最低位是链表首,最后一位是链表尾。所以在逆顺输出链表。

* 4 直到循环结束

*入口参数:numa,numb,result字符串

*出口参数:无

*--------------------------------------------------------------------------*/



void multiply(char *numa, char *numb ,char *result)//用来储结果的)//计算乘积

{

 char *pna = findend(numa);//指向numa的一个指针。point numa      pna 指向乘数的最低位,

 char *pnb = findend(numb);//指向numb的一个指针                 //pnb 指向被乘数的最低位,

 int along=(int)strlen(numa);//标记数字a的长度;

 int blong=(int)strlen(numb);//标记数字b的长度;

 int  carry=0,temp_result;//存贮进位  和临时结果的

 Node *head,   // 用于存贮头指针

  *pstart,  // 用于存贮计算时的首指针

  *pnew,    //作于申请新结点 

  *pgo;     //作为每计算完一行时,回到下一行起始节点用,移位标致来用

 head = pstart =new Node;//初始化首结点和头结点。



 pstart -> data = 0;

 pstart -> next = NULL;

 pstart -> ahead = NULL; 



 while (along--)

 {

  pgo = pstart;//保存进位点

  blong = (int)strlen(numb);//初始化长度

  pnb = findend(numb); //初始化指针

  while ((blong-- && (blong>=0))|| carry != 0)

  {    

   if(!pstart->next)//假如当前为空结点,则申请新结点

   {

    pnew = new Node;

    pnew -> data = 0;

    pnew -> next = NULL;

    pnew -> ahead = pstart;

    pstart -> next = pnew;

   }



   if(blong<0)temp_result = carry ;//处理只有进位的情况

   else temp_result =(pstart->data (*pna-48)*(*pnb-48) carry);//自身值 新值 进位作为新值   

pstart -> data = temp_result;  //存贮个位

   carry = temp_result/10;           //存贮进位

   pstart = pstart -> next;          //结点移动         

   pnb--; //指针移向被乘数高位

  }

  pstart = pgo->next; //前进一个位置;

  pna--;   //指针移向乘数高位

 }



 pstart =head;//寻找链表的结尾点

 while(pstart->next != 0)

 {

 pstart->data  = 48;//!!<<<因为我们的输出是字符。所以再此加上48>>>>  逆顺输出

 pstart = pstart->next ;

 }



    int tip = 0;//转为字符串用

 pstart = pstart->ahead ;//找有效字

 while(pstart != 0)//输出正序的结果;

 {

    result[tip  ] = pstart->data; 

 pstart = pstart->ahead ;

 }

 result[tip] = '\0';



 pstart =head;  //释放空间

 while(pstart->next != 0)

 {

 pnew = pstart->next ;delete pstart;

 pstart =pnew; 

 }

   return ;

}




网友回复:
引用 6 楼 laolaoliu2002 的回复:
任何一个数都可以表示成指数形式,如下所示: N=nEe (0= <n的绝对值 <=1,e为10的指数幂)
例如100可以表示成1E2,1001可以表示成1.01E3

只是记数的方式吧,,再说进行运算时估计也不方便
网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



/*--------------------------------------------------------------------------

*函数名称: 大数除法2-- 

*函数想法:1 用指针指向除数的最高位,保存临时字符串; tempstr[a  ] = pna

* 2 假如临时字符串大于被除数,则相减。结果等于余数

* if(tempstr>numb)tempstr = tempstr - numb

* 3 假如小于被除数且指针到头,余数 等于 临时字符串

* if(tempstr * 

*入口参数:numa,numb,result,remainder字符串

*出口参数:无

*--------------------------------------------------------------------------*/



void divide2( char *numa, char *numb,char *result,char *remainder)//计算除法2

{

 char one[]="1";//临时字符串....

    char one2[]="1";//

 char zero[]="0";//

 char numb2[6048];//

 char tempstr[6018]="";//临时字符串

 int  ia=0,ia2=0;//tempstr的指示器

 bool  moveon=false;//翻转牌



    char *pna = numa;//指向numa的一个指针。point numa      pna 指向减数的最低位,

 char *pnb = findend(numb);//指向numb的一个指针                 //pnb 指向被减数的最低位,

 Node *head,   // 用于存贮头指针

  *pstart,  // 用于存贮计算时的首指针

  *pnew;    //作于申请新结点 

  

 head = pstart =new Node;//初始化首结点和头结点。

 pstart -> data = 0;

 pstart -> next = NULL;

 pstart -> ahead = NULL; 



 moveon = false;



 while(*pna)

 {

     if(!pstart->next)//假如当前为空结点,则申请新结点

  {

   pnew = new Node;

   pnew -> data = 0;

   pnew -> next = NULL;

   pnew -> ahead = pstart;

   pstart -> next = pnew;

  }

 

        ia=(int)strlen(tempstr);//取的长度



   tempstr[ia  ] = *(pna  );    

 

        tempstr[ia] ='\0'; //转换为字符串



   if(tempstr[0]=='0')//处理高位也是0的那种 如00

   {

    ia2=0;

    while(tempstr[ia2]=='0')  ia2;

     while(ia2>=1)//清除无用的0

     {

      ia=ia2-1;

      tempstr[ia]=tempstr[ia2];

      --ia2;

     }

     tempstr[  ia2]='\0'; 

   }



  while(abigerb(tempstr,numb)>0)//假如tempstr大于等于numb

  {    

   if(tempstr[0]=='0')//处理高位也是0的那种 如00----此乃冗余代码,留做记念用            

{

    ia2=0;

    while(tempstr[ia2]=='0')  ia2;

    if(ia==ia2 )

    {

    moveon = true;

     break;

    }

   }



   strcpy(numb2,numb);

   subtract(tempstr, numb,tempstr);//A-B

   strcpy(numb,numb2);



   if(tempstr[0]=='-')//若判定的不准,变为了负数就再加上B。。   

{

    strcpy(numb2,numb);

    addition(tempstr, numb,tempstr);//A-B

    strcpy(numb,numb2);



    ia2=0; //修正之后的长度。因为加法中未做负数运算

ia=0;  //为了消除最后的那一个负号,整体向前移动。



    while(tempstr[ia2]!='\0')  ia2;     

    while(ia2>=1)//清除无用的0

     {

      tempstr[ia]=tempstr[ia 1];

        ia;

      --ia2;

     }

     tempstr[ia]='\0'; 

    moveon = true;

    break;

   }



   pstart->data   ; //结果自加

            moveon = true;

  }

  if(moveon) pstart = pstart -> next;          //结点移动

 }

 strcpy(remainder,tempstr);//存贮余数



    int tip = 0;//转为字符串用

 pstart =head;//寻找链表的结尾点

 while(pstart->next != 0)

 {

 pstart->data  = 48;//!!<<<因为我们的输出是字符。所以再此加上48>>>>  逆顺输出

 result[tip  ] = pstart->data; 

 pstart = pstart->next ;

 }

 result[tip] = '\0';//存贮结果



 pstart =head;  //释放空间

 while(pstart->next != 0)

 {

 pnew = pstart->next ;delete pstart;

 pstart =pnew; 

 }

   return ;

}




网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



/*--------------------------------------------------------------------------

*函数名称: 大数幂

*函数想法:1 B自减1直到,,作为循环控制变量.保存结果; 

* 2 结果初值1 每次乘以A

* 3 重复1、2步骤到结束. 

*入口参数:numa,numb,result字符串

*出口参数:无

*--------------------------------------------------------------------------*/

void power (char *numa, char *numb,char *result) //计算幂

{ char one[]="1"; //临时字符串....

char one2[]="1"; 

char zero[]="0"; 

char numb2[6048]; 

char remainder[6048]; 

strcpy(result,one); //给结果初值为1

strcpy(numb2,numb);



subtract(numb,one ,remainder); //B自减1

strcpy(numb,numb2);



strcpy(numb2,numb);

multiply(result,numa,result ); //A自己乘自己

strcpy(numb,numb2); 



while(strcmp(remainder,zero)>0) //A大于相等B时 就是numb不等于0时

{

strcpy(numb2,numb);

multiply(result,numa,result ); //A自己乘自己

strcpy(numb,numb2); 

strcpy(one,one2);

subtract(remainder,one ,remainder); //B减一

}



return ;

}




网友回复:高手哦等我好生看看。
网友回复:to jieao111 :int是怎么定义的,呵呵
网友回复:自己定义数组保存

这个问题在很多地方涉及到
大数阶乘啊,除法小数点后面保留n位啊之类的
csdn上就有很多现成的
lz自己搜下
关键字:表示,超出,long,double,表示,

文章评论

共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面