web-dev-qa-db-ja.com

コンピュータのハードドライブ上の16進形式とストレージ:半分のバイトで保存されますか?

私はコンピューターの専門家ではないことを前置きさせてください。何より、情報に興味があります。

コンピュータサイエンスの専門家との会話で、73829182093などの10進数値の文字列は、16進システムを利用することで、必要なバイトの半分しか占有しないハードドライブに保存できると言われました。専門家が言ったように、6つの10進数の文字列は3バイトとして格納できます。これは、各数値が4ビットのサイズしかない16進数で表すことができるためです。これはハードドライブのストレージに関して正しいですか?表示に必要なメモリではなく、ハードドライブ上のストレージを参照していることに注意してください。

私の以前の理解では、すべての情報はハードドライブにバイナリ形式(0と1)で保存され、最新のコンピューターハードドライブでは8ビットのブロックに保存されていました。そして、その16進数は、情報のdisplayを容易にするために使用されるため、人間は長いビットブロックを読み取る必要がありません。

これが当てはまる場合、これは、特定のシナリオで、16進ストレージの下のハードドライブ上の8ビットのブロックが、文字の8フルビットではなく、2つのハーフバイトのデータをエンコードすることを意味しますか?文字「M」のように?または、ハードドライブでは、ハーフバイトは実際には完全な8ビットで表され、表示時に省略されますか?

ありがとうございました。

4
J. J.

私の以前の理解では、すべての情報はハードドライブにバイナリ形式(0と1)で保存され、最新のコンピューターハードドライブでは8ビットのブロックに保存されていました。また、その16進数は情報の表示を容易にするために使用されるため、人間は長いビットブロックを読み取る必要がありません。

それは100%正しいです。 16進数は単なるデータの表現です。他の形式と比較して、16進数の性質について特別なことは何もありません。データ圧縮などは有効になりません。

あなたの友人が言及していたのは、数字を文字列として表す数字を数字として表すの違いだと思います。

符号なし整数(0から特定の固定された最大数までのビット(0と1)での数の表現)の場合、Nビットで表すことができる最大数は2 ^ Nから1を引いたものです。 0から始めます。

したがって、8ビット(別名1バイト)がある場合は、情報を失うことなく、0から255までのすべての数値を表すことができます。 0から1までのこれらの8ビットを操作して、0から255までのすべての数値を明確に表すことができます。または、必要に応じて1から256まで。それは問題ではありません。ただし、コンピューターは0から始まるものを表す傾向があります。

16ビット(2バイト)の場合、0から65535までのすべての数値を表すことができます(つまり、2 ^ 16-1)。 32ビット、0から4294967295までのすべての数値。64ビット、0から1.8の数値までのすべての数値19個のゼロ

代数から、2 ^ Nが指数関数であることがわかるかもしれません。つまり、64ビットは8ビットよりも8倍多いビットですが、その8倍以上にwayより多くのデータを格納できます。数よりビット数255*8(これはたった2040年です!)。 2040は、約180000000000000000000に比べて非常に小さい数値です。また、64ビットでは、0からその最大値までのすべての数値を格納できます。

この方法で格納された整数の興味深い意味の1つは、プログラマーがストレージの大きさを決定する必要があることです事前にストレージの大きさを決定します。これにより、特定の整数で表すことができる最大数が決まります。ストレージが処理できるよりも大きな数を格納しようとすると、overflowという名前になります。これは、たとえば、8ビット整数が255に設定されていて、コンピューターに1を加算するように要求した場合に発生します。まあ、0から255の範囲の整数内で256を表すことはできません!通常は、最初に「ラップアラウンド」して0に戻ります。

are「arbitrary-precision」と呼ばれるモードで数学を実行するプログラムは、処理される数値の大きさに応じてストレージのサイズを自動的に変更し、ますます大きくなります。たとえば、255に100000を掛けた場合、答えは8ビットを超えて16ビットを超えて大きくなる必要がありますが、32ビット整数内に収まります。数値を入力したり、64ビット整数の最大値よりも大きい数値を生成する数学演算を実行したりすると、さらに多くのスペースを割り当てる必要があります。


ただし、数字を文字列として表す場合、各数字は、散文のletterと同じスペースを占めます。 「ASDF」と「1234」はまったく同じスペースを占めます。 「OneTwoThreeFourFive」(19文字)は「1234567890123456789」と同じスペースを占めます。必要なスペースの量は、数字(または文字、または文字、一般的に)の数に応じて線形増加します。これは、各文字が文字セット内の無数の文字のいずれかを表すことができ、数字は文字セット内の単なる文字であるためです。ゼロと1の特定のシーケンスは、数値「3」を生成し、別のシーケンスは「4」を生成します。

通常、文字は8ビットまたは16ビットを使用して格納されますが、一部の文字encodingsは、文字に応じて可変数のビットを使用するか(UTF-8など)、常により多くのビットを使用します。ビット(UCS-32など)。

各文字が8ビットを取る場合、「OneTwoThreeFourFive」と「1234567890123456789」は両方とも152ビットを取ります。ただし、「1234567890123456789」は64ビット符号なし整数内に収まります。これは...64ビットのみを消費します。これは88ビットの節約です!また、Zip、7-Zip、RARなどの「データ圧縮」トリックも使用しませんでした。

5
allquixotic

私の以前の理解では、すべての情報はハードドライブにバイナリ形式(0と1)で保存され、最新のコンピューターハードドライブでは8ビットのブロックに保存されていました。また、その16進数は情報の表示を容易にするために使用されるため、人間は長いビットブロックを読み取る必要がありません。

あなたの以前の理解は正確であり、あなたはこの答えの残りの部分をすでに理解しているように感じますが、とにかく人々がしばしば混同するいくつかのアイデアを説明したいと思います。できるだけ簡潔にしようと思いますが、大変です。

バイト、ストレージ

データは通常、バイトと呼ばれる8ビットブロックでハードドライブ(またはメモリ)に保存されます。 1ビットには2つの可能な値があり、慣例により、0と1と呼びます。したがって、1バイトには2があります。8 = 256の可能な値。

なぜ8ビットブロックが典型的なユニットなのか、実際にはわかりません。私はそれを知るのに十分なコンピュータ開発の歴史に精通していませんが、少なくとも私たちは継続一般的なシステムで8ビットバイトを使用していると言うことができますこの時点で一種のロックインされており、変更する理由はありません。

また、これが発生することはわかっているので、実際には、データは必ずしも1バイトブロックまたは一度に1バイトでドライブに保存されるとは限りません。一般的なハードドライブは、多くの場合、より大きなブロックなどを使用します。ただし、質問の範囲では、これは重要ではありません。重要なのは、ハードドライブが個々のバイトで動作することが私たちに表示されることです。実際の実装は興味深いトピックですが、ここでは影響しません。従来、人間は一般に個々のバイトの観点からストレージについて議論し、おそらく are humanです。

バイナリ、16進数

バイトのようなビット関連のものの値を議論するときにバイナリ表記をよく使用する理由は、それが最も理にかなっているからです。ビットには2つの可能な値があるため、これは当然、数値の2進表現に変換されます(2進数は、各桁に10の可能な値がある、通常毎日使用する10進法とは対照的に、各桁に2つの可能な値があることを意味します)。

私たちプログラマーも16進表記(各桁には16の可能な値があります)表記を使用するのが好きな理由は、それが本当に便利だからです。たまたま、1桁の16進数で表現できる範囲は、4桁の2進数で表現できる範囲に正確に対応しています。そして、これは8ビットバイトにうまく適合します。2つの16進数は、バイトのすべての値を表すことができます。それは私たちの脳にとって管理しやすいシステムでもあり、慣れれば16進数を2進数に関連付けるのは本当に簡単です。

書面でbase-256システムを使用することもできましたが、簡単に入力でき、話しやすく、覚えやすい256の文字を思い付くのは難しいため、これは不便です。基数17のシステムを使用することもできましたが、それは8桁の2進数にうまく対応していません。したがって、16進数を使用します。これは、私たちにとって非常に理にかなっているためです。

テキスト

私たちはテキストを頻繁に使用するので、毎日使用する文字を一連のバイトとして表す標準的な方法を考え出すことは私たちの利益になります。この文字からバイトへのマッピングは、「文字エンコード」または「文字セット」と呼ばれます。もちろん、私たちは実際に物事に同意するのが苦手です。また、そのようなマッピングはさまざまなニーズに合わせて独自に開発されているため、ASCII、ISO-8859-1、または [〜# 〜] jis [〜#〜]

余談ですが、Unicodeは、すべての人を満足させる標準を定義するために考案されたもので、さまざまな文字エンコードをすべて統合しているため、「unicode」という名前が付けられています。

ただし、重要なのは、テキストは一連のバイトで表され、各一連のバイトの意味はさまざまな文字エンコードによって決定されます。バイトがテキストを表すという事実は、バイトを読み取るプログラムがそれを理解しているという前提に依存しています。それらはテキストを表すことになっています。 ASCIIは、各文字が正確に1バイトにマップされ、非常に古く、非常に単純で、非常に広く使用されており、グローバルコミュニティには非常に不十分であるにもかかわらず、話すのに便利です。まだ非常に人気があり、議論するのは簡単です。

セマンティクス

これは、多くの人にとって最も紛らわしい点だと私は確信しています。

バイトは単なるバイトです。それらは本質的に任意の値を持っています。それらの値が実際に何であるかmeanは、コンテキストと、それらを読み取るプログラムが実際にそれらを使用して行うことによってのみ決定されます。

たとえば、バイトが256の値を取ることができることを思い出すと、1日の終わりに値97(バイナリ01100001、16進数61)は、多くの異なることを意味する可能性があります。

  • バイトが整数値として扱われる場合、それは数値97です。
  • バイトがASCII文字として扱われる場合、それは文字aです。
  • バイトがIntelx86互換プロセッサのマシン命令として扱われる場合、それはPOPAまたはPOPAD命令です(これらが何であるかがわからなくてもかまいません、それは重要ではありません)。
  • バイトがグレースケール画像のピクセルを表す場合、おそらく このグレーの色合い です。
  • バイトがゲームのマップデータの一部である場合は、木やフェンスなどです。
  • 等。

数値の場合でも、ビットパターンはさまざまな意味を持ちます。たとえば、次のようになります。

  • 0〜255の値で満足できる場合があります。また、負の数を処理したい場合は、セマンティック値の範囲を-128から127にシフトし、最初のビットを使用して負であるかどうかを示します。または何でも。空が限界です(ただし、文字エンコードと同様に、整数値についても一般的に合意された一連の標準ルールがあります)。
  • さまざまな状況が原因で、整数値を他の方法でエンコードすることもあります。 [〜#〜] bcd [〜#〜]
  • より大きな整数を表す必要がある場合があります。したがって、多くのバイトを使用します。これにもオプションがあります。 "endianness" を参照してください。
  • 10進数を表す必要がある場合があります。ここにも多くのオプションがあります。ここのオプションについては、 浮動小数点 および 固定小数点 を参照してください。

このすべてのポイントは、バイトは単なるバイトであり、コンテキストが得られるまでは何の意味もありません。プログラムが意図した意味でいくつかのバイトを書き込む場合、それらを読み取り、同じ意味を持つものとして解釈するプログラムだけが、それを適切に理解することができます。

これをすべてまとめる

だから今、これをすべてあなたの答えに関連付けると、これは実際には本当に簡単なはずです:

  • あなたの友人は、あなたが数値を 16進数ので表したテキスト表現として格納するという考えに言及しています。たとえば、16進数の値97は61の場合があります。これは2桁の数字で、文字「6」の後に「1」が続きます。 [〜#〜] ascii [〜#〜] としてエンコードされます。これは2バイトになります。値54の後に値49(10進数)が続きます。 しかし、それは、それらのバイトを読み返して、それらが2つのASCIIエンコードされた16進数であると理解した場合にのみ意味があります。
  • 値97を格納することもできます。これは1バイトだけです。これは前のオプションの半分の長さです。しかしもちろん、これは、そのバイトを読み返して、整数値に直接対応していると理解した場合にのみ意味があります。

通常、私たちプログラマーはおそらく2番目のオプションを選択しますが、それは実際にはコンテキストに依存します。たとえば、人間が読めるテキストになるように設計されたHTMLドキュメントでは、width="97"のような属性を格納します。確かに、ここでより厳密な表現を使用するために必要なスペースは少なくて済みますが、HTMLを作成するのは面倒です。したがって、それは実際にはコンテキストとユースケースに依存します。

私はこれの少なくともいくつかが理にかなっていることを願っています。

3
Jason C

6つの10進数の文字列を3バイトとして格納できます

これは、BCD、2進化10進数、表現と数値のように聞こえますASCII文字(1桁あたりのフルバイト)。0から9までの値を表すために4ビットが使用されます(他の6つの値は未定義です) /無効。)
BCD値は、アンパック(1バイトあたり1 BCD桁)またはパック(1バイトあたり2 BCD桁)できます。

BCDと2進数を使用する利点は、人間による表示の利便性(つまり、簡単な変換)と、小数部の精度の低下がないことです(たとえば、10分の1は無限に繰り返される2進数です)。

電卓は通常、バイナリではなくBCD表現を使用します。クレジットカードおよびセキュリティ/アクセスカードの長い数字列は、通常、磁気ストライプまたは送信されたRFパケット)でBCD文字列としてエンコードされます。
デジタルコンピュータは通常、計算と保存にバイナリ表現を使用します。 CPUには、BCD演算を実行するための命令がある場合があります。

0
sawdust