C 如何在内存中存储任意大的整数值?
我必须存储一个大于长数据类型最大值的整数值。如何在内存中存储和操作此值C 如何在内存中存储任意大的整数值?,c,memory-management,integer,integer-arithmetic,C,Memory Management,Integer,Integer Arithmetic,我必须存储一个大于长数据类型最大值的整数值。如何在内存中存储和操作此值 如果可能的话,请通过一个例子加以说明。我不会给出代码,但我可以提出一些方法建议: 尝试将该值存储为字符串并进行转换以执行计算 尝试将该值拆分为多个整数,表示该值的一部分 查找可能为您解决此问题的现有库 祝你好运可能的解决方案: 1) 定义足够大以容纳该值的自定义整数类型。128位整数大到足以容纳98475747399。 2) 使用任何可用的图书馆。这是大学计算机科学入门课上的常见问题。焦点的主要领域是理解如何(整数)数字作为
如果可能的话,请通过一个例子加以说明。我不会给出代码,但我可以提出一些方法建议:
1) 定义足够大以容纳该值的自定义整数类型。128位整数大到足以容纳98475747399。
2) 使用任何可用的图书馆。这是大学计算机科学入门课上的常见问题。焦点的主要领域是理解如何(整数)数字作为二进制数字存储,和B)数据结构的基本知识,如果编程语言本身不能提供所需的数据结构,则可以在C++中使用元或集合结构,例如<代码>结构> <代码>,在C++中使用<代码>类< /代码>,或用Pascal记录
那么,较小的整数是如何存储在计算机中的呢?在C语言中,数据类型有char、short、int、long,它们都可以用来存储各种大小的整数。(在本次讨论中,我将忽略long
)为了通用性,假设在给定的32位平台上,大小分别为8位、16位、32位和64位。考虑可以表示的值(简化考虑未签名)。
现在,如何存储一个不能存储在无符号64位长度中的较大整数?创建自己的大整数数据类型,由多个较小(但标准)的整数组成,以便它们表示较大的值
我认为这应该为您指明正确的方向,使您能够为家庭作业或考试问题编写自己的答案。考虑使用以下结构将数字存储为十进制数字序列:
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
现在,有几个问题:
- 如何将一个添加到
num
- 如何向
num
中添加任意一位数字
- 如何将两个
num
s添加到一起
- 如何将一个
num
乘以二
- 如何将一个
num
乘以一个数字
- 如何将一个
num
乘以10
- 如何将两个
num
s相乘?提示:做一些纸笔乘法,看看它们是如何工作的
如果您完成了这一系列问题,您应该能够为每个步骤编写一个函数,并重复使用这些函数来回答后面的问题,最终得到一个非常简单且未优化的长整数包,用于正数的加法和乘法
其他问题:
- 如何将
num
概括为既表示负数又表示正数
- 如何将一个
num
除以另一个(忽略余数)?这比乘法要复杂,但还是要从铅笔和纸的长除法开始,仔细想想你在做什么
如果只是为了显示,我建议使用c标准库中的
(用于臭名昭著的printf)或者
进行一些修改。结构digitcontainer
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
}
{
结构digitcontainer*左;
结构digitcontainer*右;
无符号字符数字;
}
结构延长器
{
字符符号;
结构digitcontainer*第一位数字;
}
//1000位正数
无效测试()
{
结构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;
对于(inti=1;iright=(struct digitcontainer*)malloc(sizeof(digitcontainer));
左->右->左=左;
左->右->数字=(无符号字符)i;
左=左->右;
}
左->右=空;
//免费为您使用完该号码的每个digitcontainer拨打电话
}
Robert Lafore——C++面向对象程序设计,第四版:
// 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.cpp
//实现非常长的整数类型
#包括“verylong.h”//verylong的头文件
//--------------------------------------------------------------
void verylong::putvl()常量//显示verylong
{
煤焦温度[SZ];
strcpy(temp,vlstr);//复制
cout>vlstr;//从用户获取字符串
vlen=strlen(vlstr);//查找其长度
strrev(vlstr);//将其反转
}
//--------------------------------------------------------------
verylong verylong::operator+(const verylong v)//添加verylong
{
煤焦温度[SZ];
int j;
//查找最长数
intmaxlen=(vlen>v.vlen)?vlen:v.vlen;
int carry=0;//如果总和>=10,则设置为1
对于(j=0;jvlen-1)?0:vlstr[j]-“0”;//获取数字
int d2=(j>v.vlen-1)?0:v.vlstr[j]-“0”;//获取数字
int digitsum=d1+d2+进位;//添加数字
如果(digitsum>=10)//如果有进位,
{digitsum-=10;进位=1;}//将总和减少10,
其他的
// 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
};
#include <stdio.h>
int main()
{
unsigned long x=18446744073709551615;
printf("%lu",x);
return 0;
}