long データ型の最大値より大きい整数値を格納する必要があります。この値をメモリに保存して操作するにはどうすればよいですか?
可能であれば、例を通して説明してください。
long データ型の最大値より大きい整数値を格納する必要があります。この値をメモリに保存して操作するにはどうすればよいですか?
可能であれば、例を通して説明してください。
次のような構造体を使用して、数値を 10 進数のシーケンスとして格納することを考えてみてください。
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
の を一緒に追加しますか?num
2 を掛けますか?num
a に 1 桁を掛けるにはどうすればよいでしょうか。num
aに 10をどのように掛けますか?num
2 つの sをどのように乗算しますか? ヒント: 鉛筆と紙で掛け算をしてみて、どうなるか見てみましょう。この一連の質問に取り組むと、ステップごとに関数を記述し、それらの関数を再利用して後の質問に答えることができ、最終的には非常に単純で最適化されていない long (MAXDIGIT
数字まで)になるはずです。正の数の足し算と掛け算のための整数パッケージ。
その他の質問:
num
正の数だけでなく負の数も表すために、どのように一般化しますか?num
余りを無視して、どのように割りますか? これは掛け算よりもトリッキーですが、繰り返しますが、鉛筆と紙で割る数回の割り算から始めて、何をするかを慎重に考えてください。可能な解決策:
1) その値を保持するのに十分な大きさのカスタム整数型を定義します。128 ビット整数は、98474737475747374739399 を保持するのに十分な大きさです。
2) 利用可能なbignumライブラリを使用します。
コードは提供しませんが、取るべきアプローチについていくつかの提案を行うことができます。
幸運を
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
};
これは、大学のコンピュータ サイエンスの入門クラスでよくある質問です。主な重点分野は、a) (整数) 数が 2 進数として格納される方法を理解すること、および b) データ構造の基本 (プログラミング言語が目的のデータ構造自体を提供しない場合は、メタ構造またはコレクション構造を使用できる) です。 、struct
C、class
C++、またはrecord
Pascal など。
では、より小さな整数はどのようにコンピューターに格納されるのでしょうか? C にはchar, short, int, long
、さまざまなサイズの整数を格納するためにすべて使用できるデータ型があります。(この議論では無視long long
します。) 一般化のために、特定の 32 ビット プラットフォームでは、サイズがそれぞれ 8 ビット、16 ビット、32 ビット、および 64 ビットであるとしましょう。表すことができる値を検討してください (単純化するために、符号なしと見なされます)。
では、符号なし 64 ビット long では格納できない、より大きな整数を格納するにはどうすればよいでしょうか? より大きな値を表すように、複数の小さい (ただし標準の) 整数で構成される、独自の大きな整数データ型を作成します。
これは正しい方向を指し示し、宿題や試験の問題に対する独自の回答を書くことができるようになると思います.
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
}
表示専用の場合は<stdio.h>
、c標準ライブラリから(悪名高いprintfの場合)、または<string.h>
変更を加えることをお勧めします。