ビットはどのようにしてメモリに保存されるのでしょうか?(塊で?複数のサイズのビットを一緒に保存できますか?)

StackOverflow https://stackoverflow.com/questions/1546381

質問

私は以前、各メモリ位置には 8、16、32、または 64 ビットが含まれていると考えていました。したがって、0101 は 8 ビット マシンでは 00000101 (負の場合は符号拡張) として格納されます。このシステムの内部動作をさらに知りたいという好奇心から Java でプログラムを作成するまでは、これですべてがうまくいきました。

問題のメソッドは次のようになります。

public void printBinaryRep(File f){
        try{
            FileInputStream inputStream = new FileInputStream(f);
            int next = 0;
            byte b = 0;
            while((next = inputStream.read()) != -1){
                b = (byte)next;
                System.out.println((char)next + " : "+Integer.toBinaryString(next));
            }
            inputStream.close();
        }
        catch(Exception e){System.out.println(e);}
 }

Hello World というファイルからこの出力を取得しました

H : 1001000
e : 1100101
l : 1101100
l : 1101100
o : 1101111
  : 100000
W : 1010111
o : 1101111
r : 1110010
l : 1101100
d : 1100100

スペース以外はすべて問題ないようです。ビット数は 8 ビットではなく 6 ビットです。私は今、そのすべての情報がどのようにしてメモリに保存されているのか疑問に思っています。すべてが 8 ビットのチャンクに保存されている場合、次のようになります。

こんにちは:10010001100101110110011011001101111

その後、各 8 ビットのチャンクを単純に見て、それがどの数値を表しているのか (そして、それがどの ASCII コードを参照しているのか) を把握することができます。異なるサイズの文字 (6 ビットのスペースや 4 ビットの /n など) が一緒に保存された場合、どのように動作しますか??それでは、大きなビット空間に小さな数値を格納すると、大量のビットが無駄になるのではないか?

私の根本的な理解が間違っていると思います(あるいは、プログラムのどこかが間違っている可能性もあります...)。質問が奇妙に聞こえたり、不必要に詳しくなりすぎたりしたら、申し訳ありません。ただ知りたいだけです。いくつかグーグルで調べてみましたが、関連するものは何も見つかりませんでした。どこが間違っていたのか、または正しい方向を教えていただければ、大変感謝いたします。ありがとう!

役に立ちましたか?

解決

あなたは、Cおよび/またはアセンブリではなく、Javaで実験したほうが良いでしょう。これらの言語は、低レベルであり、直接アドレス空間を公開します。

  

私は、各メモリと思うために使用しました   位置8、16、32又は64を含んでいます   ビット。だから、0101は8に格納されます   00000101としてビットマシンは(符号拡張します   それは陰性であった場合)。これは、すべて大丈夫でした   そして、ダンディ私はプログラムを書いたまで   いくつかを見つけるために好奇心のうちのjava   このシステムのより多くの内部の仕組みます。

x86システムのすべてのメモリ位置は、8ビット(1バイト)を含みます。値が単一バイトに収まることができるよりも多くのデータが含まれている場合は、複数のバイトを使用して格納されます。例えば、Cに、 "フロート" 型は、4バイト(32ビット)を使用して格納されます。

  

それはすべてを除いて正常に見えます   スペース。これは、6ビットの代わりに8私はを持っています   今それをどのようにすべてを疑問に思います   情報がメモリに保存されています。もし   そのすべては、8ビットのチャンクに格納されていました、   

のような

スペースは、単一のバイトに格納されます。あなたの印刷コードは8つのスペースに出パッドに忘れています。 100000 == 00100000 == 0x20にます。

他のヒント

スペースがあまりにも8ビットです。それはInteger.toBinaryStringが有力0ビットにあなたがそれを使用する方法を印刷していないことだけです。

すべての主要0ビットで、それが実際にメモリに次のようになります:

H : 01001000
e : 01100101
l : 01101100
l : 01101100
o : 01101111
  : 00100000
W : 01010111
o : 01101111
r : 01110010
l : 01101100
d : 01100100

は元の直観は(ほとんど)正しかった:すべてのメモリ位置は、同じビット数から成ります。すべての近代的なマシンでは、バイトはマシンが個別にアクセスできるメモリの最小のチャンクである「バイト」、の8ビットがあります。

あなたの出力をよく見ます。あなたは、スペースを除いて、それらのすべてでの 7 の数字を持っています。スペースだけで、他の文字が1で始まりながら、そのバイナリ表現に2つのゼロから始めることが起こるます。

実際にあなたのアプローチが間違っています。エンコーディングは、ここで非常に重要です。

あなたはASCIIを使用する場合、あなたは簡単に各文字がバイト(8ビット)に格納されていることを言うことができますが、変更をエンコードするとき、あなたはそれを言うことはできません。

例:UTF-8文字列の各文字に対して1〜3個のバイト(8〜24ビット)を使用します。あなたがたInputStreamオブジェクトのエンコーディングを指定できるオーバーロードが表示されます理由です。

間違った入力ストリームを選択することは絶対に間違った文字列の出力を発生します。したがって、あなたは何を意味しているビットを理解するために、ファイルのエンコーディングを知っている必要があります。実際のFileInputStreamはあなたのためにこれを行います。

あなたは文字列として数字を格納する場合は、

これは、ハードドライブに炭化長がかかります。ただ、別の文字が好きでます。

あなたはASCIIエンコーディングを文字列として123456789を保存する場合は、

しかし、それは、9 * 8ビット= 72ビットとなります。

あなたは整数、(その整数のデータ幅が異なる環境で異なります注意してください)としてこれを保存する場合は、

これは16ビットのみになります。

また、あなたは確認することができない。

H : 01001000
e : 01100101
l : 01101100
l : 01101100
o : 01101111
  : 00100000
W : 01010111
o : 01101111
r : 01110010
l : 01101100
d : 01100100
\n: 00001010
01001000:

はHとしてハードドライブに格納されています E:01100101 L:01101100 L:01101100 O:01101111   :00100000 W:01010111 O:01101111 R:01110010 L:01101100 D:01100100 \ n個:00001010

あなたはそれを確認することはできません。ファイルシステムはそれほど単純ではありません。たぶん、こんにちは連続ですが、世界の文字列は、ドライブの最後にあります。ザッツなぜデフラグコマンドがあります。

しかし、私たちはメインメモリ(RAM)について話す場合は、文字列を定義するとき、私は、ビットは、連続することを期待しています。少なくともCでそれがあります。あなたはそのような文字列を定義します。

char[100] value; // c is a char array. (there is no string type in c)

ここでの値は、[0]私たちの文字列の最初の文字です。その値は、メモリ内のチャーアレイの場所に対処するものである。

値[0]のアドレスが10、値[1] 'の場合

のアドレスは、10 + 8 = 18である。

方法コンピュータの店舗数は、車の中でオドメーターと比較することができます。オドメーターは4桁の数字を持っている場合、それは「0033」として数33を格納します。

誰かがの尋ねられた場合、あなたはあなたの走行距離が何であるか、あなたは「ゼロ千ゼロ百33」を言うつもりはありません。デフォルトでは、Javaはどちらかありません。 (あなたはそれを伝えることができますが。)

  
    

次に大きなビット空間の少数ビットの多くを無駄に格納していないのでしょうか?

  

まあ、そうでもありません。あなたがどこかにメモリに11000100を持っていたとします。どのようにコンピュータがこのように11000100、または11000 100、または1 100に続いて1000年に続いて続くことを意味し、かどうかを知ることになっている?

まあ、実際にコンピュータはちょうどそれが指定されているプログラム(Javaプログラムの一部があなたによって、一部のJavaを設計人々によって作成されたことを覚えておいてください)以下の通りです。あなたはビットを保存するための実行可能なシステムを作成することができる場合は、コンピュータがそれを行うことができます。

ただし、プロセッサの使用状況やプログラミングの難易度の面でトレードオフがあることに注意してください。典型的なコンピュータはバイトで動作することができますので、の多くののより迅速に、それは7ビットまたは可変ビット番号、バイト単位でASCIIコードを格納すると、テキストを格納するための非常に一般的な選択である、と言うでできるよります。

しかし、私は、あなたの質問に戻りましょう。

  
    

次に大きなビット空間の少数ビットの多くを無駄に格納していないのでしょうか?

  

数学的に言えば、ありません。絶対に必要なビット数が依存ことを教えてくれるの情報理論と呼ばれる数学の枝可能性はあなたがエンコードしたいとそれらのそれぞれがどのように可能性が高い。

のは、あなたがそれを表現する唯一の4文字のアルファベット(それぞれ00、01、10、11)(A、B、C、D)、および使用する2つのビット数を有していると仮定しよう。これらの文字の各々が等しく可能性がある場合には、(平均して)文字ごとに必要なビットの最小数はすなわち2である、は存在しないの無駄ビットなかっAは00であり、Bは01であってもます。

一方、ASCIIを使用して、次の7ビット数としてA、B、C、Dをコードする場合:

A: 1000001
B: 1000010
C: 1000011
D: 1000100

そして、あなたは(あなたは「大規模なビット空間に小さな数字を保存」していないにもかかわらず)文字ごとに5ビットを「無駄」されます。

の配慮のこれらの種類は、圧縮アルゴリズムを設計する際に重要であり、そしてeverdayアプリケーションにそれほど重要ではありません。あなたがCを学びたい場合には、ビットとバイトを理解することは確かに重要です。

による Java 4 API,

符号なし整数値は、引数が負の場合は引数に 232 を加えたものになります。それ以外の場合、それは引数に等しくなります。この値は、追加のリーディング0Sがないバイナリ(ベース2)の一連のASCII桁に変換されます。

実際には、データ ストレージはさらに複雑です。処理効率を高めるため、ほとんどのデータ型はワード境界に格納されます。つまり、32 ビット マシンでは 4 バイト、64 ビット マシンでは 8 バイトになります。配列はより密にパックされる可能性があるため、 char [4] 最終的には同じ量の「実際のスペース」を使用することになる可能性があります。 char.

Java は仮想マシンですが、Java がどのようなメモリ アーキテクチャを使用しているのかはわかりません。

それはそれをクリア。私の主な問題は、私は最初にゼロを見下ろすたということでした。 Iは、圧縮アルゴリズム(すなわち、GZIP)の詳細を読んでいたとして、私はこれを実験しました。 私はこのすべてのASCIIを想定しました。表現を見ることは、プログラムの目標ではありませんでしたが、単語ごとに異なる数のビットは、私が働いているファイルタイプのための基本的な、インデックスベースの圧縮を実現するための本来の目的から私を投げました。私はJavaで概念実証を持っていたら、Cでそれを書き直してみます。

ありがとうございます。

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#toBinaryString%28int%29
Integer.ToBinarys の仕様は次のようになります。

「この値は、バイナリ(ベース2)の一連のASCII桁に変換され、追加のリーディング0Sはありません」

あなたがこの事実を見落としていたことが、あなたの混乱を引き起こしたのです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top