9

明らかに、標準はこれについて何も述べていませんが、私は実用的/歴史的な観点からもっと興味がありcharます. そうしないと、null ターミネータの 2 つの表現や、すべての「バイト」値を表現できないなど、あらゆる種類の奇妙さが潜在的に発生しますchar。この奇妙なシステムは本当に存在しますか?

4

3 に答える 3

6

文字列を終了するために使用されるヌル文字は、決して 2 つの表現を持つことはできません。次のように定義されています (C90 でも):

null 文字と呼ばれる、すべてのビットが 0 に設定されたバイトは、基本実行文字セットに存在する必要があります。

そのため、1 の補数に「負のゼロ」を使用することはできません。

とはいえ、2 の補数以外の C 実装については、ほとんど何も知りません。大学時代には 1 の補数計算機を使用していましたが、あまり覚えていません (当時は標準を気にしていたとしても、それは存在する前のことでした)。

于 2011-05-29T00:54:25.170 に答える
5

確かに、商業的に生産されたコンピュータの最初の 10 年間または 20 年間 (1950 年代と 60 年代) は、負の数を 2 進数で表現する方法について意見の相違があったようです。実際には次の 3 つの候補がありました。

  1. 戦争に勝利しただけでなく、他を絶滅に追い込んだ2の補数
  2. 1の補数、-x == ~x
  3. サインマグニチュード、-x = x ^ 0x80000000

最後の重要な 1 補数マシンはおそらく CDC-6600 で、当時は地球上で最速のマシンであり、最初のスーパーコンピューターの直前のマシンでした。1.

残念ながら、ここに誰も答えを知らないからではなく、選択を行う必要がなかったため、あなたの質問に実際に答えることはできません. そして、これには実際には次の2 つの理由がありました。

  1. 2 の補数は、バイト マシンと同時に引き継がれました。バイト アドレッシングは、2 の補数を持つ IBM System/360 によって世界に広まりました。以前のマシンにはバイトがなく、完全なワードのみがアドレスを持っていました。プログラマーはこれらの単語の中に文字を詰め込むこともあれば、単語全体を使用することもあります。(ワード長は 12 ビットから 60 ビットまで変化します。)

  2. C は、バイト マシンと 2 の補数の移行から 10 年後に発明されました。項目 1 は 1960 年代に発生し、C は 1970 年代に最初に小さなマシンに登場し、1980 年代まで世界を席巻しませんでした。

したがって、マシンが署名付きバイト、C コンパイラ、および 2 の補数データ形式以外のものを持っていた時代はありませんでした。ヌル終端文字列という考え方は、アセンブリ言語のプログラマーが次々と考案した設計パターンの繰り返しだったのかもしれませんが、C の時代までコンパイラで指定されていたかどうかはわかりません。

いずれにせよ、最初に実際に標準化された C (「C89」)は単に「値ゼロのバイトまたはコードが追加される」ことを指定しており、数値形式に依存しないようにしようとしていたことは文脈から明らかです。したがって、「+0」は理論上の答えですが、実際には存在しなかった可能性があります。


1. 6600 は歴史的に最も重要なマシンの 1 つでしたが、それは単に高速だったからではありません。Seymour Cray 自身によって設計され、アウトオブオーダー実行と、後にまとめて「RISC」と呼ばれるその他のさまざまな要素が導入されました。他の人も自分の功績を称えようとしましたが、Seymour Cray は RISC アーキテクチャの真の発明者です。彼がスーパーコンピュータを発明したことに異論はない. 彼が設計していない過去の「スーパーコンピューター」に名前を付けるのは実は難しい.

于 2011-05-29T00:59:33.360 に答える
2

システムが 1 の補数の 'char' 型を持つことはほとんど可能ではありますが、まったく可能ではないと思いますが、すべてを解決できない 4 つの問題があります。

  1. すべてのデータ型は、2 つのオブジェクトを構成するすべての char 値が同一であると比較すると、問題のデータ オブジェクトが同一になるように、一連の char として表現可能でなければなりません。
  2. 同様に、すべてのデータ型は「unsigned char」のシーケンスとして表現可能でなければなりません。
  3. 任意のデータ型を分解できる unsigned char 値は、順序が 2 のべき乗であるグループを形成する必要があります。
  4. 標準では、1 の補数マシンが負のゼロになる値を特殊なケースに入れ、それを別のものとして動作させることを許可しているとは思いません。

負のゼロを取得する唯一の方法が他のデータ型をオーバーレイすることである場合、および負のゼロが正と等しくない場合、1 の補数または符号の大きさの "char" 型を備えた標準準拠のマシンを使用できる可能性があります。ゼロ。それが標準に準拠しているかどうかはわかりません。

編集

ところで、要件 2 が緩和された場合、他のデータ型を「char」にオーバーレイするときの正確な要件はどうなるのだろうか? とりわけ、標準では、別の変数を「char」にオーバーレイした結果として生じる可能性のある「char」値に対して割り当てと比較を実行できなければならないことが十分に明確になっていますが、それが要件を課していることはわかりません。そのような値はすべて算術群として振る舞う必要があります。たとえば、すべてのメモリ位置が物理的に 66 ビットとして格納され、上位 2 ビットが値が 64 ビット整数か、32 ビット メモリ ハンドルと 32 -ビットオフセット、または64ビットの倍精度浮動小数点数ですか?標準では、算術計算が符号付きの型の範囲を超えた場合に実装が好きなことを行うことが許可されているため、符号付きの型は必ずしもグループとして動作する必要がないことが示唆されます。

ほとんどの符号付き型では、その型が limits.h で指定された範囲外の数値を表すことができないという要件はありません。limits.h で最小の "int" が -32767 であると指定されている場合、-32768 の値を実際に許可する実装は完全に正当です。これを試みたプログラムは未定義の動作を呼び出すためです。重要な問題は、他のタイプのオーバーレイの結果として生じる「char」値が、limits.h で指定された範囲外の値を生成することが正当であるかどうかということでしょう。標準は何を言っているのだろうか?

于 2011-05-29T01:20:46.033 に答える