20

CおよびC++標準では、数値の特定の表現が規定されていないことを知っています(2の補数、符号と大きさなど)。しかし、ビットを操作するときに特定の制限/保証/予約された表現があるかどうかを知るのに十分な基準を知りません(そしてそれが述べられているかどうかを見つけることができませんでした)。特に:

  1. 整数型のすべてのビットがゼロの場合、整数は全体としてゼロを表しますか?
  2. 整数型のビットが1の場合、整数は全体としてゼロ以外を表しますか?(これが「はい」の場合、符号と大きさなどの一部の表現はさらに制限されます)
  3. ビットが設定されていないかどうかを確認する保証された方法はありますか?
  4. ビットが設定されているかどうかを確認する保証された方法はありますか?(#3と#4は#1と#2に依存します。たとえば、ある変数の5番目のビット(#5を参照)を設定する方法を知っているのでx、変数をチェックしてy、それが5番目のビットは1ですが、機能するかどうかを知りたいですif (x & y)(私が理解しているように、これは表現の値に依存し、そのビットが実際に1または0であるかどうかではありません))
  5. 左端および/または右端のビットを設定する保証された方法はありますか?(少なくとも、char cすべてのビットをtrue(で設定c = c | ~c)にして、ハイビットとロービットc = c << (CHAR_BIT - 1)を設定するよりも簡単な方法です。これらの質問を前提として、私がすべきではないという仮定をしていません)。c = c ^ (c << 1)
  6. #1の答えが「いいえ」の場合、整数型のビットを繰り返し処理して、それぞれが1か0かを確認するにはどうすればよいでしょうか。

私の全体的な質問は次のとおりです:整数の表現が義務付けられていないという事実にもかかわらず(そしてこの点でCとC ++の標準が異なる場合)、ビットと整数に関してCとC++の標準によって作成された制限/保証/予約された表現はありますか、それらの違いは何ですか)?

私は宿題をしているときにこれらの質問を思いついたので、少し操作する必要がありました(これらは宿題からの質問ではなく、はるかに「抽象的な」ものであることに注意してください)。

編集:私が「ビット」と呼んでいるものに関しては、「値形成」ビットを意味し、「パディング」ビットは含まれていません。

4

8 に答える 8

16

(1)整数型のすべてのビットがゼロの場合、整数は全体としてゼロを表しますか?

はい、すべてゼロで構成されるビットパターンは常に0を表します。

整数型の表現は、純粋な2進記数法を使用して値を定義するものとします。49 [§3.9.1/7]

49 2進数の0と1を使用する整数の位置表現。連続するビットで表される値は加算され、1で始まり、2の連続する整数乗が乗算されます。ただし、おそらく最も高い位置にあるビットは除きます。


(2)整数型のビットが1の場合、整数は全体としてゼロ以外を表しますか?(これが「はい」の場合、符号と大きさなどの一部の表現はさらに制限されます)

いいえ。実際、符号付きの大きさは特に許可されています。

[例:この国際規格では、整数型の2の補数、1の補数、および符号付きの大きさの表現が許可されています。—例を終了] [§3.9.1/7]


(3)ビットが設定されていないかどうかを確認する保証された方法はありますか?

署名されたタイプを考えると、これに対する答えは「いいえ」だと思います。これは、すべて1のビットパターンを使用した等価性テストと同等です。これは、すべて1のビットパターンを使用して符号付き数値を生成する方法がある場合にのみ可能です。符号なしの数値の場合、この表現は保証されますが、数値が表現できない場合、符号なしから符号付きへのキャストは未定義です。

宛先タイプが署名されている場合、宛先タイプ(およびビットフィールド幅)で表すことができれば、値は変更されません。それ以外の場合、値は実装定義です。[§4.7/3]


(4)ビットが設定されているかどうかを確認する保証された方法はありますか?

符号付きの大きさが許可されているため、私はそうは思いません。0は-0に等しいと比較されます。ただし、符号なしの数値でも可能です。


(5)左端および/または右端のビットを設定する保証された方法はありますか?

繰り返しになりますが、答えは符号なしの番号では「はい」ですが、符号付きの番号では「いいえ」です。負の符号付き数値のシフトは定義されていません。

それ以外の場合E1、符号付きタイプと非負の値があり、E1×2 E2が結果タイプで表現可能である場合、それが結果の値になります。それ以外の場合、動作は定義されていません。[§5.8/2]

于 2012-08-25T21:35:06.290 に答える
9

「すべてのビット」という用語を繰り返し使用しますが、どの「すべてのビット」を指しているのかを明確にしません。C / C ++での整数型のオブジェクト表現には、値形成ビットパディングビットが含まれる場合があります。パディングビットがないことが保証されている唯一の整数型はです[signed/unsigned] char

言語は、すべての値形成ビットがゼロの場合、表される整数値もゼロであることを常に保証していました。

パディングビットに関しては、物事は少し複雑です。C言語の元の仕様(C89 / 90および元のC99)は、すべてのオブジェクトビットをゼロに設定すると有効な整数表現が生成されることを保証しませんでした。無効なトラップ表現が生成された可能性があります。つまり、元のC(および最初はC99)memset(..., 0, ...)で整数型を使用しても、オブジェクトが有効なゼロ値を受け取ることは保証されませんでした(を除く[signed/unsigned] char)。これは、後の仕様、つまりC99の技術的な基準の1つで変更されました。ここで、整数オブジェクト(パディングを含むすべてのビットを含む)のすべてゼロのビットパターンが有効なゼロ値を表す必要があります。

つまり、最近のCではmemset(..., 0, ...)、整数オブジェクトをゼロに設定するために使用することは合法ですが、C99以降にのみ合法になりました。

于 2012-08-25T21:42:59.257 に答える
2

整数値の表現については、すでにいくつかの回答があります。メモリ内で表されるオブジェクトのすべての個々のビットを提供することが保証されている方法は1つだけです。それは、の配列として表示することですunsigned char。これは、パディングビットがなく、トラップ表現がないことが保証されている唯一の整数型です。したがって、最初のバイトにのみアクセスする限り、T*オブジェクトへの型のポインタをキャストすることは常に機能します。これにより、すべてのバイト(したがってビット)を調べて好みに合わせて設定できます。unsigned char*sizeof(T)

詳細に興味がある場合は、ここでCの整数型の構造について説明しました。C++はそれとは少し異なる場合があります。特にunion、説明されているように型をピン処理することは、C++では十分に定義されていないようです。

于 2012-08-25T22:10:01.350 に答える
1

Q:整数型のビットが1の場合、整数は全体としてゼロ以外を表しますか?(これが「はい」の場合、符号と大きさなどの一部の表現はさらに制限されます)

いいえ。CおよびC++の標準では、符号付きの大きさまたは1の補数を除外していません。どちらも+0と-0です。+0と-0は等しく比較する必要がありますが、同じ表現である必要はありません。

符号付きの大きさまたは1の補数を使用する最近のマシンを見つけて頑張ってください。

于 2012-08-25T21:36:59.540 に答える
0

整数型のすべてのビットがゼロの場合、整数は全体としてゼロを表しますか?

編集:パディングビットに関心がないことを明確にしたので、これに対する答えは実際には「はい」です。しかし、私はオリジナルを残します:

必ずしもそうとは限りませんが、トラップ表現である可能性があります。C996.2.6.1を参照してください。

unsignedchar以外のunsignedintegerタイプの場合、オブジェクト表現のビットは、値ビットとパディングビットの2つのグループに分割されます(後者のいずれかである必要はありません)。

パディングビットの存在により、すべての0がトラップ表現である可能性があります。(以下のコメントでKeith Thompsonが指摘しているように、最近のC11は、そのような表現がトラップ表現ではないことを明示しています)。

パディングビットの値は指定されていません

44)パディングビットの組み合わせによっては、トラップ表現が生成される場合があります

質問を値ビットと符号ビットに制限すると、6.2.6.2により、答えは「はい」になります。

N個の値ビットがある場合、各ビットは1〜2 N −1の間の2の異なる累乗を表すため、そのタイプのオブジェクトは、純粋なバイナリ表現を使用して0〜2 N −1の値を表すことができます。これは、値表現と呼ばれます。

符号ビットがゼロの場合、結果の値に影響を与えることはありません。

整数型のビットが1の場合、整数は全体としてゼロ以外を表しますか?(これが「はい」の場合、符号と大きさなどの一部の表現はさらに制限されます)

必ずしもそうとは限りません。実際、6.2.6.2では符号と大きさが明示的にサポートされています。

ビットが設定されていないかどうかを確認する保証された方法はありますか?

パディングと符号ビットを気にしない場合は、0と比較することもできますが、すべてのビット0とすべてのビット1の両方が値0を表すため、これは1の補数表現(許可されています)では機能しません。

それ以外の場合:を介して各バイトの値を読み取り、unsigned char *結果を0と比較できます。

unsignedビットフィールドおよびunsignedchar型のオブジェクトに格納されている値は、純粋なバイナリ表記を使用して表す必要があります。

特定の値のビットをチェックしたい場合は、(1u << n)を使用して適切なビットマスクを作成できますが、これによって必ずしも符号ビットを検査できるとは限りません。

ビットが設定されているかどうかを確認する保証された方法はありますか?

答えは基本的に前の質問と同じです。

左端および/または右端のビットを設定する保証された方法はありますか?

左端のビットを意味しますか?タイプに応じて、INT_MAXまたはUINT_MAXまたは同等のビットをカウントし、それを使用して1 << n、元の値とORする値を(経由で)作成できます。

#1の答えが「いいえ」の場合、整数型のビットを繰り返し処理して、それぞれが1か0かを確認するにはどうすればよいでしょうか。

繰り返し左シフトしたビットマスクを使用してこれを行うことができますが、この方法ではビットのみをチェックでき、符号ビットはチェックできません。

于 2015-02-04T13:08:30.607 に答える
0

脳を爆発させたい場合は、次のことを考慮してください。intまたはlongまたはlong longをunsignedcharの配列として解釈する場合(これは、すべてのビットを表示したい場合に行うのが最も合理的な方法です)、バイトの順序は定義されていません。たとえば、「bigendian」と「littleendian」のようになります。私たちは皆(願わくば)それを知っています。

ただし、さらに悪いことに、intの各ビットは、charの配列の任意のビットに格納できます。だから32があります!本当に奇妙な実装によって、32ビット整数のビットを4つの8ビット符号なし文字の配列にマッピングする方法。幸いなことに、私は2つ以上の方法に遭遇したことはありません(実際のコンピューターでもう1つ注文することを知っています)。

于 2015-02-19T14:44:18.357 に答える
-1

ビット操作の場合、8つの1つの符号なしビットフィールドを持つ構造体を作成し、その構造体のポインターが文字を指すようにすることができます。このようにして、各ビットに簡単にアクセスできます。しかし、コンパイラーはおそらく内部でマスキングを行うので、プログラマーにとってはよりクリーンな方法にすぎないと思います。これを行うときは、コンパイラがフィールドの順序を変更しないことを確認する必要があります。

yourstruct* pChar=(yourstruct*)(&c)
pChar.Bit7=1;
于 2012-08-25T21:14:28.453 に答える
-1

私が一般的にCとC++(たとえば、C90以下、MS Visual C ++など)に取り組んでいると言って、これに注意しましょう:「最大公約数」(vs.最新/最大のcx11「標準」)。

Q:整数型のすべてのビットがゼロの場合、整数は全体としてゼロを表しますか?

A:はい

Q:整数型のビットが1の場合、整数は全体としてゼロ以外を表しますか?(これが「はい」の場合、符号と大きさなどの一部の表現はさらに制限されます)

A:はい。これには、signedintの符号ビットが含まれます。私は率直に言って「大きさ」に精通していません

Q:ビットが設定されていないかどうかを確認する保証された方法はありますか?

A:ビットマスクの「And'ing」は常に保証されています。

Q:ビットが設定されているかどうかを確認する保証された方法はありますか?

A:繰り返しになりますが、ビットマスクの「and'ing」は常に保証されています。

Q:左端および/または右端のビットを設定する保証された方法はありますか?

A:左端のビットを決定するために、すべての実装/すべてのアーキテクチャで常に「MAX_INT」を使用できるようにする必要があると思います。

私は炎上する準備ができています...しかし、上記は正確だと思います。そして、それがお役に立てば幸いです。

私見では...

于 2012-08-25T21:15:02.530 に答える