なぜそれほど多くの数値型(bit、int、float、double、long)があるのですか?


9

PHP、Java、Cを学びました。ビット、整数、浮動小数点数、倍精度浮動小数点数、長整数型など、非常に多くの種類の数値データ型がある理由について知りたいと思います。数値のタイプを1つだけにしないでください。

これには何かメリットがありますか?たぶん、そのような小さな数を保持するために整数を使用すると、メモリを節約できますか?


6
HorusKolの答えに加えて、「float」型と「integer」型は本質的に異なります。フロートは非常に大きな数値を保持できますが、数値のサイズが大きくなると、精度が低下します。この不正確さは、フロートの格納方法が原因です。対照的に、整数に格納できる値の範囲は非常に限られていますが、値は常に正確であるため、値の比較がはるかに簡単になります。また、除算には2つの異なるタイプの動作があります-整数は自動的に最も近い整数に「切り捨て」られますが、浮動小数点はそうではありません。これらの各動作は、さまざまな状況で役立ちます。
カンプ2013年

JavaScriptは、表面上に1つの数値タイプしかありません。
エサイリヤ2013年

@kampu:実際、多くの言語では、(仮想)メモリがそれを表すのに十分な大きさである限り、整数は任意の数を格納できます。
イェルクWミッターク

1
@JörgWMittag:しかし、その質問者は明らかにPythonなどの動的言語ではなく、静的言語について話しているのです。CPython自体は、32ビットの整数の配列として「無制限の範囲」の整数を実装します。各整数の最後のビットを使用して、さらに多くのビットがあるかどうかを示します。また、整数は任意の保存することができます全体の数だけを。つまり、無限のストレージを持つフロートは、値を精度(infinity aleph one)に格納できますが、整数は値を精度(infinity aleph zero)にのみ格納できます。
カンプ2013年

@kampu:すべての数値は一連のビットで表されるため、無限のストレージがあっても、浮動小数点数と整数の間には常に1対1のマッピングがあります。だから私はアレフが疑問に思うようになるとは思わない。
から来る

回答:


17

異なる数値データタイプを考慮する必要がある理由は2つあります。

1.メモリの節約

for(long k=0;k<=10;k++)
{
    //stuff
}

簡単に整数、またはバイトになる可能性があるのに、なぜlongを使用するのですか?そうすることで、実際に数バイトのメモリを節約できます。

2.浮動小数点数と整数はコンピュータに異なる方法で保存されます

整数に22が格納されているとします。コンピュータは、次のようにこの数をバイナリでメモリに保存します。

0000 0000 0000 0000 0000 0000 0001 0110

2進数システムに慣れていない場合、これは2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 +のように科学表記法で表すことができます。 2 ^ 5 * 0 + ... + 2 ^ 30 * 0。最後のビットは、数値が負かどうかを示すために使用される場合とされない場合があります(データ型が符号付きか符号なしかによって異なります)。

基本的に、これは2 ^(ビットプレース)*値の合計です。

これは、小数点を含む値を参照しているときに変わります。10進数で3.75という数値があるとします。これは、バイナリでは11.11と呼ばれます。これを科学表記として2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1または1.111 * 2 ^ 2として正規化して表すことができます

ただし、コンピューターはそれを格納できません。2進小数点(小数点の2進数システムバージョン)を明示的に表現する方法はありません。コンピュータは1と0しか保存できません。これが浮動小数点データ型の出番です。

sizeof(float)が4バイトであるとすると、合計で32ビットになります。最初のビットには「符号ビット」が割り当てられます。符号なしfloatまたはdoubleはありません。次の8ビットは「指数」に使用され、最後の23ビットは「仮数」(または仮数と呼ばれることもあります)として使用されます。3.75の例を使用すると、指数は2 ^ 1になり、仮数は1.111になります。

最初のビットが1の場合、数値は負です。そうでない場合、肯定的です。指数は「バイアス」と呼ばれるものによって変更されるため、単純に「0000 0010」を指数として格納することはできません。単精度浮動小数点数のバイアスは127で、倍精度(これはdoubleデータ型がその名前を取得する場所)のバイアスは1023です。最後の23ビットは仮数用に予約されています。仮数は、2進小数点のRIGHTに対する値です。

私たちの指数は、バイアス(127)+指数(1)またはバイナリで表されます

1000 0000

私たちの意味は次のようになります:

111 0000 0000 0000 0000 0000

したがって、3.75は次のように表されます。

0100 0000 0111 0000 0000 0000 0000 0000

ここで、浮動小数点数と整数として表される8を見てみましょう。

0100 0001 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1000

コンピュータはどのように8.0と8を追加するのですか?またはそれらを掛ける!?コンピューター(より具体的には、x86コンピューター)には、浮動小数点数と整数値を追加するCPUのさまざまな部分があります。


3
3)まれに問題になりますが、コンピューターのワードサイズよりも大きい数値の操作は遅くなります。
Loren Pechtel 2013年

6

ギガバイトシステム(またはArduinoのような最新の組み込みシステム)が登場する前は、メモリは非常に高価でした。そのため、特定の数値が占めるメモリの量を指定するための簡略化されたメソッドが実装されました。メモリの。

他のデータサイズと名前はシステムによって異なります。32ビットシステムでは、INT(またはMEDIUMINT)は通常2バイト、LONGINTは4バイト、SMALLINTは1バイトです。64ビットシステムでは、LONGINTを8バイトに設定できます。

現在でも-特にデータベースアプリケーション、またはサーバー上で実行されている複数のインスタンス(ウェブサイトのサーバー側スクリプトなど)を持つプログラムでは-何を選択するかに注意する必要があります。2、4、または8バイト幅の整数を選択して0〜100(1バイトに収まる)の値を格納することは、数百万のレコードを持つデータベーステーブルがある場合、非常に無駄です。

詳細:https : //en.wikipedia.org/wiki/Integer_(computer_science)


いい答え+1。
Vinay 2013年

7
「以前に戻る」だけでなく、「システムが小さいときの今」も。Arduinoのサイズのデバイスでは、経済的でなければなりません。
9000

1
どのシステムが1ビットのみを使用してビットを格納しましたか?通常、ビットは直接アドレス指定できません
jk。

1
それは多くのアーキテクチャに当てはまりますが、ビットは本当に古いシステムで直接アドレス指定可能であり、さらに最近の組み込みシステム(10年前にプログラムした一部のコントローラはビ​​ットで動作しました-それらは特定の幅のアドレス指定可能な場所が約64しかありませんでした)。今日では、コンパイラがそれを解決してバイト配列に入れていると思います。
HorusKol 2013年

最も重要な要素は、メモリの問題ではなく、CPUの能力とパフォーマンスにあると思います
James

4

メモリ不足と精度、および範囲のトレードオフに関するcpmjr123の優れた点に加えて、これらは潜在的にCPUのトレードオフでもあります。

最近のほとんどのマシンには、FPUと呼ばれる浮動小数点演算を実行するための特別なハードウェアがあります。FPUが搭載されていないシステムもあります(現在、これらは通常、小さな組み込みデバイスです)。そのため、ターゲットハードウェアに応じて、浮動小数点型をまったく使用しないか、ソフトウェアの浮動小数点ライブラリを使用する必要があります。マシンにFPUが搭載されていても、提供できる機能には歴史的に違いがありました。ハードウェアで実行されない機能は、ソフトウェアで実行する(または回避する)必要があります。

ソフトウェアで浮動小数点計算を行うには、ハードウェアがサポートする多くの単純な操作を実行します。したがって、速度のトレードオフの可能性もあります。


4

おそらく最も重要なことは、実際には3つの異なる基本的な数値タイプがあることです。

整数、固定小数点、浮動小数点。

それらはすべて異なる動作をします。

7/2のような単純な操作では、使用するデータ型に応じて、3、3.50、3.499の回答が得られます。

「固定10進数」はシンデレラ型であり、COBOLやVisualBasicなどのいくつかの言語でネイティブにのみサポートされています。これはコンピュータサイエンティストにはほとんど関心がありませんが、一連のアカウントを送信したり、請求書で消費税を計算したりする人には不可欠です。


私はそれらを別々に分離します:離散数、近似数、およびラッピング代数リング。Cにおける典型的な例は次のようになりintfloat、およびunsigned intそれぞれ。固定小数点型は離散型のサブカテゴリですが、代数環は基本的に数値とは異なります[Cの符号なし型に関する混乱の大部分は、数値ではなくリングのように動作するが、完全に一貫していないという事実に由来します] 。
スーパーキャット2014年

3

彼らがそれを作る利点はありますか?

もちろん。メリットがあります。コンピュータの世界では、メモリは考慮すべき最も重要なことの1つです。データが1 kb未満に収まる場合、2 kbのメモリを使用する用途は何ですか?。最適化が必要です。より多くのメモリを使用すると、ある時点で明らかにコンピュータの速度が低下します。本当に食べたいですか?権利はありません...?

int - 2 bytes (16 bits)

long - 4 bytes (32 bits)

long long - 8 bytes (64 bits)

float - 4 bytes

記憶だけでなく、数字の種類の整理もあります。インスタンスの浮動小数点。精度は非常に重要であり、さらに精度を上げることができるタイプが1つ必要です。

昔を考えると、ご存知のように記憶が非常に少なかったのです。保存して賢く使用するために、これらの違いがありました。さらに、先に進んでgoogle。で検索してみてください。これがお役に立てば幸いです。


3

整数と実数(float、double)の数値は、概念的には異なる型であり、演算と組み込みプロパティのセットが異なります。

整数は列挙可能ですが、浮動小数点はそうではありません。

実際、Float / double数値は、仮数と指数の2つの整数フィールドを組み合わせた構造です。複素数(考慮から除外したもの)はさらに複雑です。

実用的な言語では、少なくとも整数と浮動小数点数を別個の型として持つ必要があります-それらに対する操作が多すぎます。


私はあなたが言った「複素数」に精通していません。さらに説明できますか?
cpmjr123 2013年

これを確認してください:en.wikipedia.org/wiki/Complex_number
c-smile

a + biの形の複素数を知っています。コンピューターが複素数をどのように保存するかについて、もっと情報を求めていました。私の知る限り、これをサポートする基本的なデータ型はありません。
cpmjr123 2013年

複素数は通常、2つの浮動小数点値、つまりa(実部)とb(虚部)として格納されます。CPUは通常、複素数の演算のネイティブサポートを実装していませんが、CPUは、(a b + c d)や(a b-c d)などの値のペアの演算のための加速乗加算命令を実装できます。
2013年

1
さらに、多くの言語にはいくつかの型があり、その動作は主にラッピング代数環の動作として定義されています(たとえば、型の変数uint16_tが65535を保持している場合、インクリメントすると0に保持されます)。理想的には、言語は、折り返しの代数リングと数値を表すために明確に分離された型を持つことになります(オーバーフローする数値をトラップし、コードがラップすることが予想されるものに対して操作を簡単に実行できるようにします)。
スーパーキャット2014

-1

浮動小数点型の動作が整数型とは完全に異なるという事実に加えて、数値あたりのサイズが本当に重要である理由をもっと極端に示したいと思います。

(長い)配列をソートしたいとします。たとえばCの場合:

int numbers[100000000];

つまり、ここには1億の数値があります。

各数値の長さが1バイトしかない場合(のunsigned char代わりにを使用int)、これには1億バイトのスペースが必要です。

を使用するdouble場合、これは通常、数値あたり8バイトであるため、8億バイトのスペースになります。

したがって、多数のオブジェクト(この例では数値)を操作するたびに、オブジェクトあたりのサイズ(この例では数値あたりのサイズ)が本当に重要になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.