16

我必须存储一个大于 long 数据类型最大值的整数值。我将如何在内存中存储和操作这个值?

如果可能,请举例说明。

4

8 回答 8

24

考虑使用如下结构将数字存储为十进制数字序列:

struct num {
    int ndigits;
    char d[MAXDIGITS];
};

例如,数字 123456 可以初始化为

struct num n = { 6, { 6, 5, 4, 3, 2, 1 } };

事实证明,颠倒的数字顺序对于轻松计算很重要。特别是,位值n.d[i]n.d[i]* 10^i。

现在,有几个问题:

  • 您将如何将一个添加到 a num
  • 您如何将任意单个数字添加到 a num
  • 你如何将两个nums 加在一起?
  • 你将如何将 a 乘以num2?
  • 你如何将 a 乘以一位num数?
  • 你如何将 a 乘以num10?
  • 你如何将两个nums 相乘?提示:做一些铅笔和纸的乘法,看看它们是如何工作的。

如果您完成了这一系列问题,您应该能够为每个步骤编写一个函数,并重新使用这些函数来回答后面的问题,并最终得到一个非常简单且未优化的 long(嗯,最多MAXDIGIT位数)整数包,用于正数的加法和乘法。

其他问题:

  • 你如何概括num来表示负数和正数?
  • 你如何除以num另一个(忽略余数)?这比乘法更棘手,但同样,先用铅笔和纸做一些长除法,然后仔细考虑你要做什么。
于 2010-02-13T05:06:54.473 回答
8

可能的解决方案:
1)定义足够大以容纳该值的自定义整数类型。128 位整数足以容纳 98474737475747374739399。2
) 使用任何可用的bignum库。

于 2010-02-12T15:49:56.640 回答
4

我不会给你代码,但我可以就采取的方法提出一些建议:

  1. 尝试将值存储为字符串并转换以执行计算
  2. 尝试将值分解为多个整数,表示值的一部分
  3. 查找可以为您解决此问题的现有库

祝你好运

于 2010-02-12T15:40:52.800 回答
3

Robert Lafore - C++ 中的面向对象编程,第 4 版:

// verylong.cpp
// implements very long integer type
#include "verylong.h"          //header file for verylong
//--------------------------------------------------------------
void verylong::putvl() const           //display verylong
   {
   char temp[SZ];
   strcpy(temp,vlstr);                 //make copy
   cout << strrev(temp);               //reverse the copy
   }                                   //and display it
//--------------------------------------------------------------
void verylong::getvl()                 //get verylong from user
   {
   cin >> vlstr;                       //get string from user
   vlen = strlen(vlstr);               //find its length
   strrev(vlstr);                      //reverse it
   }
//--------------------------------------------------------------
verylong verylong::operator + (const verylong v) //add verylongs
   {
   char temp[SZ];
   int j;
                       //find longest number
   int maxlen = (vlen > v.vlen) ? vlen : v.vlen;
   int carry = 0;                      //set to 1 if sum >= 10
   for(j = 0; j<maxlen; j++)           //for each position
      {
      int d1 = (j > vlen-1)   ? 0 : vlstr[j]-'0';   //get digit
      int d2 = (j > v.vlen-1) ? 0 : v.vlstr[j]-'0'; //get digit
      int digitsum = d1 + d2 + carry;               //add digits
      if( digitsum >= 10 )             //if there's a carry,
         { digitsum -= 10; carry=1; }  //decrease sum by 10,
      else                             //set carry to 1
         carry = 0;                    //otherwise carry is 0
      temp[j] = digitsum+'0';          //insert char in string
      }
   if(carry==1)                        //if carry at end,
      temp[j++] = '1';                 //last digit is 1
   temp[j] = '\0';                     //terminate string
   return verylong(temp);              //return temp verylong
   }
//--------------------------------------------------------------
verylong verylong::operator * (const verylong v)  //multiply 
   {                                              //verylongs
   verylong pprod;                     //product of one digit
   verylong tempsum;                   //running total
   for(int j=0; j<v.vlen; j++)         //for each digit in arg
      {
      int digit = v.vlstr[j]-'0';      //get the digit
      pprod = multdigit(digit);        //multiply this by digit
      for(int k=0; k<j; k++)           //multiply result by
         pprod = mult10(pprod);        //   power of 10
      tempsum = tempsum + pprod;       //add product to total
      }
   return tempsum;                     //return total of prods
   }
//--------------------------------------------------------------
verylong verylong::mult10(const verylong v) const //multiply
   {                                              //arg by 10
   char temp[SZ];
   for(int j=v.vlen-1; j>=0; j--)      //move digits one 
      temp[j+1] = v.vlstr[j];          //   position higher
   temp[0] = '0';                      //put zero on low end
   temp[v.vlen+1] = '\0';              //terminate string
   return verylong(temp);              //return result
   }
//--------------------------------------------------------------
verylong verylong::multdigit(const int d2) const 
   {                                   //multiply this verylong
   char temp[SZ];                      //by digit in argument
   int j, carry = 0;
   for(j = 0; j<vlen; j++)             //for each position
      {                                //   in this verylong
      int d1 = vlstr[j]-'0';           //get digit from this
      int digitprod = d1 * d2;         //multiply by that digit
      digitprod += carry;              //add old carry
      if( digitprod >= 10 )            //if there's a new carry,
         {
         carry = digitprod/10;         //carry is high digit
         digitprod -= carry*10;        //result is low digit
         }
      else
         carry = 0;                    //otherwise carry is 0
      temp[j] = digitprod+'0';         //insert char in string
      }
   if(carry != 0)                      //if carry at end,
      temp[j++] = carry+'0';           //it's last digit
   temp[j] = '\0';                     //terminate string
   return verylong(temp);              //return verylong
   }

非常长的类头

// verylong.h
// class specifier for very long integer type
#include <iostream>
#include <string.h>         //for strlen(), etc.
#include <stdlib.h>         //for ltoa()
using namespace std;

const int SZ = 1000;
        //maximum digits in verylongs

class verylong
   {
   private:
      char vlstr[SZ];       //verylong number, as a string
      int vlen;             //length of verylong string
      verylong multdigit(const int) const;   //prototypes for
      verylong mult10(const verylong) const; //private functions
   public:
      verylong() : vlen(0)             //no-arg constructor
         { vlstr[0]='\0'; }
      verylong(const char s[SZ])       //one-arg constructor
         { strcpy(vlstr, s); vlen=strlen(s); }   //for string
      verylong(const unsigned long n)  //one-arg constructor
         {                                       //for long int
         ltoa(n, vlstr, 10);           //convert to string
         strrev(vlstr);                //reverse it
         vlen=strlen(vlstr);           //find length
         }  
      void putvl() const;              //display verylong
      void getvl();                    //get verylong from user
      verylong operator + (const verylong); //add verylongs
      verylong operator * (const verylong); //multiply verylongs
   };
于 2012-05-11T20:28:09.870 回答
2

这是大学计算机科学入门课程中的常见问题。主要关注领域是 a) 了解(整数)数字如何存储为二进制数字,以及 b) 数据结构的基础知识,如果编程语言本身不提供所需的数据结构,您可以使用或集合结构,例如struct在 C、classC++ 或recordPascal 中。

那么较小的整数是如何存储在计算机中的呢?在 C 语言中,您可以使用所有数据类型char, short, int, long来存储各种大小的整数。(我将忽略long long此讨论。)为了一般性,假设在给定的 32 位平台上,大小分别为 8 位、16 位、32 位和 64 位。考虑可以表示的值(以简化考虑的无符号)。

现在,您如何存储一个不能以无符号 64 位长度存储的更大整数?制作您自己的大整数数据类型,由多个较小(但标准)的整数组成,以便它们表示较大的值。

我认为这应该为您指明正确的方向,并使您能够为作业或考试问题写下自己的答案。

于 2010-02-13T03:54:19.333 回答
0
    struct digitcontainer
    {
      struct digitcontainer* left;
      struct digitcontainer* right;
      unsigned char digit;
    }

    struct longinteger
    {
      char sign;
      struct digitcontainer* firstdigit;
    }

    // positive number with 1000 digits
    void test()
    {
      struct longinteger myNumber;

      myNumber.sign = '+';
      myNumber.firstdigit = (struct digitcontainer*)malloc( sizeof(digitcontainer) );
      myNumber.firstdigit->left = NULL;
      myNumber.firstdigit->right = NULL;
      myNumber.firstdigit->digit = 1;

      struct digitcontainer* left = myNumber.firstdigit;

      for( int i=1; i<1000; i++ )
      {
        left->right = (struct digitcontainer*)malloc( sizeof( digitcontainer ) );
        left->right->left = left;
        left->right->digit = (unsigned char)i;
        left = left->right;
      }

      left->right = NULL;

      // call free for each digitcontainer you are finished using the number
    }
于 2010-02-16T13:50:01.480 回答
-1

如果它只是为了显示,我会建议<stdio.h>来自 c 标准库的(用于臭名昭著的 printf)或者<string.h>进行一些修改。

于 2010-02-13T05:19:27.617 回答
-2

C 是一门了不起的语言,从最近几天开始,我一直在寻找在 C 中存储大值的答案。然后我终于得到了答案。使用 unsigned long 。它通常可以存储高达 18446744073709551615 的值。它最多为 20 位数字。

  #include <stdio.h>
  int main()
    {
       unsigned long x=18446744073709551615; 
       printf("%lu",x);
       return 0;
    }
于 2019-06-08T07:26:32.843 回答