質問
このコードを持っています
#include <iostream>
using namespace std;
int main(int argc,char **argv) {
unsigned long long num1 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995LL;
unsigned long long num2 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996LL;
unsigned long long num3 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997LL;
unsigned long long num4 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998LL;
unsigned long long num5 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999LL;
cout << (unsigned long long)(num1 * num2 * num3 * num4 * num5) << endl;
return 0;
}
お分かりのように、数字は膨大ですが、そこで計算すると、次のようになります。 18446744073709551496
コンパイル時に次の警告が表示されます:
warning: integer constant is too large for its type|
In function `int main(int, char**)':|
warning: this decimal constant is unsigned only in ISO C90|
...
解決
結果はlong long型よりも大きくなります- BigInteger または任意の精度ライブラリを確認する必要があります、 gmp
のようなもの他のヒント
これらの数値は、どのC ++データ型にも適合しません。単に印刷したい場合は、数字を文字列に保存します。数学を実行したい場合は、任意の精度の数学ライブラリを見つけて使用します。
コードでこれほど大きなリテラルが必要な場合は、文字列リテラルとして入力し、ある種のBigIntクラスにロードする必要があります。現在、ソースコードでこれほど大きな整数リテラルを表現する方法はありません(ただし、C ++ 0xはその不足に対処することを願っています)。
BigInteger ライブラリを使用している場合は、 stringToBigUnsigned
BigIntegerUtils.hh
のcode>関数。文字列から大きな整数を作成します。
#include "BigUnsigned.hh"
#include "BigIntegerUtils.hh"
BigUnsigned num1 = stringToBigUnsigned (
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999999999999999999999999999999999999999999999999"
"99999999999999999999999999999999999995"
);
何をしようとしているのですか? 2進数と10進数の基本を理解していますか? 8ビットが0〜255、12ビット0〜4095などの値しか保持しないのはなぜですか?興味のある数字を保持するのに何ビット必要ですか?もっと良いことに、あなたはどれくらいの数の作品を作りたいと思っていますか?そして、数字を大きくするために9を使用していますか?代わりに16進数0xFについてはどうですか? (標準の整数型のいずれかで)最大の符号なしの数値が必要な場合は、なぜですか:
unsigned long long a、b;
a = -1; //これは符号付きと符号なしの混合が間違っているように見えますが、有効であり、保存する前に数値が符号なしに変換されます
b = 0; b--; //上記と同じことを行います
そのレベルで本当に精度が必要ですか?乗算では、各オペランドの2倍のサイズの結果が必要になる場合があることを理解していますか? 0xFF * 0xFF = 0xFE01、この場合、8ビット整数を使用していた場合、計算ができませんでした。 0xFF * 0xFF * 0xFF = 0xFD02FFを掛け続けると悪化します。
何をしようとしているのですか?
応答の確認:
オイラー番号8を見たことがありません。ほんの数行のコードで解決できるので、良いインタビューの質問のように聞こえます。
他の応答:
数字...
10本の指(おそらく10本の指)があるため、「ベース10」で成長します。私たちの時計は、ほとんどの部分がベース60ですが、より混乱させるためにベース10と混合されています。とにかく、10を底とは、10個の一意の数字のうちの1つを各番号のプレースホルダーに持つことを意味します。これはすべて小学校のものです。
000
001
002
003
...
008
009
010
011
012
...
右端の桁に10個の記号(0、1、2、3、4、5、6、7、8、9)があり、最後の記号に達すると、最初の記号と左の記号が最初から始まることを確認します1ずつ増加します。この規則は、すべての基本番号付けシステムに当てはまります。
2つのシンボル、0と1のみがあることを除いて、基数2に当てはまります
000
001
010
011
100
101
...
8進数でも同じですが、8つのシンボル(0,1,2,3,4,5,6,7)
000
001
002
003
004
005
006
007
010
011
012
013
...
16進数の16シンボル(0,1,2,3,4,5,6,7,8,9、a、b、c、d、e、f)についても同様です
000
001
002
003
004
005
006
007
008
009
00a
00b
00c
00d
00e
00f
010
011
012
013
...
私は、コンピューターで他のベース(10など)よりもバイナリーを使用する理由について説明しようとしていました。結論として、2つの状態のオン/オフ、または高と低を簡単に設定できます。 2つの状態は、ベース2の2つのシンボル1と0のようなものです。利用可能な電圧内で電子機器を2つ以上の状態に調整しようとするのは困難です。比較的簡単なので、デジタルエレクトロニクスは2つの状態、バイナリを使用します。
バイナリでの人間の単純なタスクでさえ、長い時間がかかり、単純な2年生の数学はまだ多くの1と0です。 8進数は、3ビットのグループで考えることができ、数字0、1、2、3、4、5、6、7としてよく知られている記号を使用できるため、普及しました。しかし、2のべき乗である4のグループは、人間に8進数よりもはるかに精神的な計算能力を与えます。16進数は4のビットに基づいており、2のべき乗でもあります。伝統的なアラビア語のベース10。したがって、アルファベットの最初の6が使用されました。 8進数が使用されることはめったにありません。16進数の代わりに8進数を考える場合、誰かに年齢を伝えることができます。 (私はヘックス世代から来ていますが、8進数から2進数から16進数へと移行することができないため、ヘックスに苦労している8進数世代の人々と協力しています。)
コンピュートのベース10rは、16進数の平均的な人間の思考のようなものです。コンピューターはベース10を実行しません(bcdを使用した怠laな人間にとっては良い)、ベース2を実行します。コンピューターの10進数1234は実際には0x4D2または0b010011010010です。それは値として、たとえば1234にsymbos 1、2、3、および4とは関係のない値を必要とする他の数を追加したいのですが、この答えをstackoverflowに投稿するために、この数を使用しませんASCIIを使用します。したがって、asciiの1234は0x31、0x32、0x33、0x34です。これは、1000桁の数字がASCII文字列として提供されていることを前提とするオイラーソリューションにとって重要です。問題はベース10の問題であり、定義によりベース2ではないため、バイナリからアスキーへ。
それで、私が尋ねたところに戻ります。数字を保存するために4ビットのメモリがあったとしましょう。どれくらいの数字を保存できますか?ベース10のみを考える場合、数字は9であると考えるかもしれません。各保管場所で最大のシンボルを使用することを考えるように訓練されているため、ベース10に5つの保管場所がある場合、99999が最大の数ですただし、1ビットの最大のシンボルは1で、その番号を1111(4つ)を取得する各ストレージロケーションに入れます。これらの4つを見るだけで、同じ数字17の8進数またはF 16進数の8進数と16進数のバージョンを簡単に見ることができるはずです。 10進数を表示するには数学が必要です。この場合は暗記すると、その数値は10進数の15です。したがって、使用できる最大の4ビット数は0xFまたは9ではなく15です。8ビット数はどうですか。 0xFFまたは255(2の8乗-1)。最大の16ビット数? 65535など。
したがって、これを使用しようとしているビット数を尋ねると、私は意味します。この数字99999を見てください。ベース10でもこれが最大の数字だと思いますが、コンピューターにとっては10進数の99999は0x1869Fであり、17ビットのメモリーを保存できます。 storeは0x1FFFFで、131071です。これは99999より少し大きいです。したがって、コンピューターで大きな数字や数学を考えたい場合は、バイナリ(または16進数)を考える必要があります。
元々は乗算を行っていましたが、これはオイラー問題の一部ですが、私が尋ねていたのは精度とビットストレージに関連していました。ここにいくつかの基本事項がありますが、私はそれには触れませんが、コンピューターの浮動小数点ユニットに依存している理由を見ることができます。
最大の4ビット数1111(バイナリ)を取得します。これは10進数の15です。最大の4ビット数で追加すると、15 + 15 = 30 = 0x1Eまたは11110バイナリが得られます。したがって、2つの4ビット数を追加するには、答えを保持するために5ビットが必要です。コンピューターは「キャリー」を保持しますこの余分なビットのビット。基本的に、コンピューターの整数の加算/減算演算機能により、N + 1ビットを使用できます。したがって、32ビットコンピューターの場合、基本的には加算/サブ演算用に33ビットがあります。
問題は乗算と除算であり、今日でも多くのプロセッサーはサポートしていません(多くのプロセッサーはfpuを持たず、加算と減算のみを行い、時には乗算しますが、除算はまれです。ソフトウェアで加算と減算を使用してそれらを行うことができます)。 4ビットシステムで最悪の場合の乗算を行う 1111 * 1111 = 11100001 4ビット乗算の結果を格納するのに8ビットかかるため、4ビットシステムを使用したい乗算のMOSTが4に格納できない数になることがすぐにわかります。ビット。したがって、64ビット整数(符号なしlong longは多くの場合64ビット)を取り、4倍することを見たとき、それは答えを保存するために64 * 5または320ビット整数が必要であることを意味し、その答えを64の大きな結果は、コンパイラとコンピューターに応じて、幸いなことに上位ビットが切り捨てられ、結果の下位64ビットになります。これは、どのオペランドよりも簡単に小さく見える場合があります。
得られた答え18446744073709551496は、長いlongに割り当てられたときに999 ... 9が切り捨てられ、さらに複数の操作がオーバーフローするためです。その決定論的ですが、実質的にはランダムなビットのコレクションです。
unsigned intはシステムワードを表します。今日、その単語は、システムが32ビットか64ビットかに応じて、2 ^ 32 -1または2 ^ 64-1で最大になります。上限に達しています。
bignumクラスを記述するか、「net」以外のクラスを使用する必要があります。
なぜこの問題をやっているのですか?
数値は unsigned long long
の範囲に収まらないため、GMPライブラリを使用するか、文字列を使用して大きな数値を表すことができます。
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
unsigned int nd, nz;
unsigned char *ca;
unsigned int j, n=50, q, temp;
int i;
double p;
p = 0.0;
for(j = 2; j <= n; j++)
{
p += log10((double)j);
}
nd = (int)p + 1;
ca = new unsigned char[nd+1];
if (!ca)
{
cout << "Could not allocate memory!!!";
exit(0);
}
for (i = 1; (unsigned)i < nd; i++)
{
ca[i] = 0;
}
ca[0] = 1;
p = 0.0;
for (j = 2; j <= n; j++)
{
p += log10((double)j);
nz = (int)p + 1;
q = 0;
for (i = 0;(unsigned) i <= nz; i++)
{
temp = (ca[i] * j) + q;
q = (temp / 10);
ca[i] = (char)(temp % 10);
}
}
cout << "\nThe Factorial of " << n << " is: ";
for( i = nd - 1; i >= 0; i--)
{
cout << (int)ca[i];
}
// delete []ca;
return 0;
}