12

C / C ++では、ビット単位の演算子はエンディアンに依存せず、期待どおりに動作するはずだと私は理解しています。マシンのエンディアンを気にせずに、64ビット値から本当に最も重要な単語と最も重要でない単語を取得していることを確認したいと思います。次に例を示します。

uint64_t temp;
uint32_t msw, lsw;
msw = (temp & 0xFFFFFFFF00000000) >> 32;
lsw = temp & 0x00000000FFFFFFFF;

これは機能しますか?

4

8 に答える 8

17

6.5.7ビット単位のシフト演算子

4 E1 << E2の結果は、E1の左シフトE2ビット位置です。空のビットはゼロで埋められます。E1に符号なしタイプがある場合、結果の値はE1×2E2であり、結果タイプで表現可能な最大値よりも1を法として減少します。E1に符号付きタイプと非負の値があり、E1×2E2が結果タイプで表現可能である場合、それが結果の値です。それ以外の場合、動作は定義されていません。

だから、はい-標準によって保証されています。

于 2010-02-03T18:25:26.910 に答える
5

それは機能しますが、ビットシフトの前にビットマスキングを行うという一部の作者の奇妙な傾向は常に私を困惑させました。

私の意見では、はるかにエレガントなアプローチは、最初にシフトを行うものです

msw = (temp >> 32) & 0xFFFFFFFF; 
lsw = temp & 0xFFFFFFFF; 

少なくとも、毎回同じ「魔法の」ビットマスク定数を使用しているためです。

これで、ターゲットタイプが符号なしで、すでに目的のビット幅がある場合、マスキングは完全に不要になります。

msw = temp >> 32; 
lsw = temp; 
于 2010-02-03T22:35:49.130 に答える
3

はい、うまくいくはずです。mswを取得しているときは、マスクは実際にはあまり成果を上げていません。とにかくシフトを実行すると、ゼロにマスクしたビットは破棄されます。個人的には、おそらく次のようなものを使用します。

uint32_t lsw = -1, msw = -1;
lsw &= temp;
msw &= temp >> 32;

もちろん、意味のある結果を生成するにtempは、コードに含まれていなかった初期化が必要です。

于 2010-02-03T18:29:05.737 に答える
2

はい。動作するはずです。

于 2010-02-03T18:23:23.347 に答える
1

共有したい考えですが、で見つかった関数またはマクロを使用して<arpa/inet.h>、ネットワークをホストの順序に変換したり、その逆を行ったりすることで、値のエンディアンを回避できる可能性があります。ただし、このインスタンスでは、エンディアンアーキテクチャを処理するために手動でコーディングされたカスタム関数に頼るのではなく、別のプロセッサからの0xABCDなどの値がIntelx86で0xABCDのままであることを保証するために使用できます。 !!

編集:これはCodeProjectのエンディアンに関する記事であり、著者は64ビット値を処理するためのマクロを開発しました。

これがお役に立てば幸いです、よろしく、トム。

于 2010-02-03T18:52:12.533 に答える
1

エンディアンはメモリレイアウトに関するものです。シフトはビット(およびビットレイアウト)に関するものです。ワードの重要性は、メモリレイアウトではなく、ビットレイアウトに関するものです。したがって、エンディアンは単語の重要性とは何の関係もありません。

于 2010-02-03T22:38:40.407 に答える
0

他の応答に加えて、Cのエンディアンについて心配する必要はないことを付け加えておきます。エンディアンの問題は、最初にそれらのバイトを書き込むために使用されたものとは異なるタイプの一部のバイトを調べることによってのみ発生します。これを行うと、エイリアシングの問題が発生する可能性が非常に高くなります。つまり、別のコンパイラまたは別の最適化フラグを使用すると、コードが破損する可能性があります。

このようなトランスタイプアクセスを実行しようとしない限り、コードはエンディアンニュートラルであり、リトルエンディアンとビッグエンディアンの両方のアーキテクチャで問題なく実行される必要があります。つまり、エンディアンの問題がある場合は、他の種類のより大きな問題も近くに潜んでいます。

于 2010-02-03T20:45:55.673 に答える
0

あなたの言っていることはかなり真実だと思いますが、これはどこにあなたを導きますか?

リテラル値がぶら下がっている場合は、どちらの端がどちらであるかがわかります。しかし、プログラムの外部からの値を見つけた場合は、何らかの方法でエンコードされていない限り、確信が持てません。

于 2010-02-03T18:27:02.680 に答える