符号なし整数の違い-符号付き結果を取得するための標準サポートされている方法?

13
vlad_tepesch 2019-07-02 14:07.

2つの任意のタイムスタンプを想定:

uint32_t timestamp1;    
uint32_t timestamp2;

より大きな符号付きタイプへの変換とかなり冗長なif-elseのほかに、2つの符号付きの違いを取得するための標準的な適合方法はありますか?

どちらが大きいかは事前にはわかりませんが、差が最大20ビット以下であることがわかっているため、32ビット符号付きに収まります。

int32_t difference = (int32_t)( (int64_t)timestamp1 - (int64_t)timestamp2 );

このバリアントには、64ビット演算の使用がハードウェアでサポートされていない可能性があり、もちろん、より大きなタイプが存在する場合にのみ可能であるという欠点があります(タイムスタンプがすでに64ビットの場合はどうなりますか)。

他のバージョン

int32_t difference;
if (timestamp1 > timestamp2) {
  difference =    (int32_t)(timestamp1 - timestamp2);
} else {
  difference = - ((int32_t)(timestamp2 - timestamp1));
}

非常に冗長で、条件付きジャンプが含まれます。

それは

int32_t difference = (int32_t)(timestamp1 - timestamp2);

これは標準の観点から機能することが保証されていますか?

4 answers

8
Bathsheba 2019-07-02 21:13.

union基づいた型のパンニングを使用できます

typedef union
{
    int32_t _signed;
    uint32_t _unsigned;
} u;

演算を行うunsigned演算に結果を割り当てる_unsigned部材、次に読み取る_signedのメンバーをunion結果:

u result {._unsigned = timestamp1 - timestamp2};
result._signed; // yields the result

これは、依存している固定幅タイプを実装するすべてのプラットフォームに移植可能です(必要はありません)。2の補数は符号付きメンバーに対して保証されており、「マシン」レベルでは、2の補数の符号付き算術は符号なし算術と区別できません。ここには変換やmemcpy型のオーバーヘッドはありません。優れたコンパイラーは、本質的に標準的な構文糖衣構文をコンパイルします。

(これはC ++では未定義の動作であることに注意してください。)

1
M.M 2019-11-06 07:19.

バトシェバの答えは正しいですが、完全を期すために、さらに2つの方法があります(これはC ++でも機能します)。

uint32_t u_diff = timestamp1 - timestamp2;
int32_t difference;
memcpy(&difference, &u_diff, sizeof difference);

そして

uint32_t u_diff = timestamp1 - timestamp2;
int32_t difference = *(int32_t *)&u_diff;

後者は厳密なエイリアシング違反ではありません。これは、そのルールが整数型の符号付きバージョンと符号なしバージョンの間のしゃれを明示的に許可しているためです。


提案:

int32_t difference = (int32_t)(timestamp1 - timestamp2);

存在し、int32_tタイプを提供する実際のマシンで動作しますが、技術的には標準によって保証されていません(結果は実装定義です)。

0
dbush 2019-07-02 22:25.

符号なし整数値から符号付き整数への変換は、実装で定義されています。これは、整数変換に関するC標準のセクション6.3.1.3で詳しく説明されています。

1整数型の値を_Bool以外の整数型に変換する場合、新しい型で表現できる場合は変更されません。

2それ以外の場合、新しいタイプが符号なしの場合、値が新しいタイプの範囲内になるまで、新しいタイプで表現できる最大値より1つ多い値を繰り返し加算または減算することにより、値が変換されます。60)

3 それ以外の場合、新しいタイプは署名され、値を表すことができません。結果が実装定義であるか、実装定義のシグナルが発生します。

人々が使用する可能性が最も高い実装では、変換は期待どおりに行われます。つまり、符号なしの値の表現は符号付きの値として再解釈されます。

具体的には、GCCは次のことを行います。

  • 値がその型のオブジェクト(C90 6.2.1.2、C99、およびC11 6.3.1.3)で表現できない場合に、整数を符号付き整数型に変換した結果、またはそれによって生成された信号。

幅Nのタイプに変換する場合、値は2 ^ Nを法として減少し、タイプの範囲内になります。信号は発生しません。

MSVC:

長整数が短整数にキャストされるか、短整数が文字にキャストされると、最下位バイトが保持されます。

たとえば、この行

short x = (short)0x12345678L;

値0x5678をxに割り当て、この行

char y = (char)0x1234;

値0x34をyに割り当てます。

符号付き変数が符号なしに変換されたり、その逆に変換されたりしても、ビットパターンは同じままです。たとえば、-2(0xFE)を符号なしの値にキャストすると、254(これも0xFE)になります。

したがって、これらの実装では、提案したものが機能します。

0
personal_cloud 2019-11-08 02:54.

答えとしてのバトセバの答えのイアンアボットのマクロパッケージのブランド変更:

#define UTOS32(a) ((union { uint32_t u; int32_t i; }){ .u = (a) }.i)

int32_t difference = UTOS32(timestamp1 - timestamp2);

これが単純なタイプキャストよりも移植性が高い理由に関する議論を要約すると、C標準(少なくともC99に戻る)は(2の補数でなければならない)の表現を指定しますint32_tが、すべての場合にからキャストする方法を指定するわけではありませんuint32_t

最後に、Ianのマクロ、Bathsebaの回答、およびMMの回答はすべて、たとえばTCPシーケンス番号の場合のように、カウンターが0をラップアラウンドできるより一般的な場合にも機能することに注意してください。

Related questions

MORE COOL STUFF

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

OxyLEDの新しい15ドルのモーションセンシング常夜灯はどこにでも貼り付けられますが、充電が簡単です

OxyLEDの新しい15ドルのモーションセンシング常夜灯はどこにでも貼り付けられますが、充電が簡単です

私たちの読者は、何千ものOxyLEDのT-02モーションセンサーライトストリップを何年にもわたって購入してきましたが、充電するのが面倒だと感じた場合、新しいT-04は素晴らしいアップグレードのように見えます。T-02のように、 T-04は、付属の粘着ストリップを介して基本的にあらゆる表面に取り付けることができ、暗闇での動きを検出すると自動的に点灯します。

ハンソロ映画セットの写真は、新しいスーツと新しい乗り物を明らかにします

ハンソロ映画セットの写真は、新しいスーツと新しい乗り物を明らかにします

ユニバーサルは、フランケンシュタインの怪物を見つけるのに近いかもしれません。新しい撮影映像でアクマンの舞台裏をご覧ください。

ドナルド・トランプが解雇されたばかりのFBI長官ジェームズ・コミー

ドナルド・トランプが解雇されたばかりのFBI長官ジェームズ・コミー

写真:AP大統領ドナルド・トランプは、連邦捜査局長官のジェームズ・コミーを解雇したばかりです。火曜日の声明で、ホワイトハウスは、トランプが「両方の副検事総長ロッドの明確な勧告に基づいて行動するコミーをオフィスから削除したと述べましたローゼンスタインと司法長官のジェフセッション。

テオドリック大王は、過去の言語と政治的概念に隠された野蛮な将軍でした

テオドリック大王は、過去の言語と政治的概念に隠された野蛮な将軍でした

ウィキメディア・コモンズ経由西部のローマ帝国の中央機関が崩壊し、5世紀の間に州が分裂し、独自の道を進んだとき、新しい王国が出現しました。今日、私たちはこれらの新しい政治単位を特定の野蛮人グループで特定する傾向があります:ガリア南西部の西ゴート族、ガリア北部のフランク人、英国のアングロサクソン人、北アフリカのヴァンダル人。

バレンタインデーにユーカリのシャワースチーマーで「最高の睡眠」を贈りましょう。

バレンタインデーにユーカリのシャワースチーマーで「最高の睡眠」を贈りましょう。

BodyRestore ユーカリ シャワー スチーマーは、Amazon で 11,000 を超える 5 つ星の評価を得ています。セルフケアが必要な人へのバレンタインデーのギフトとして、ホームスパ製品を贈りましょう。

この「邪悪な吸引力」を備えたこの250ドルのハンドヘルド掃除機は、Amazonで75%オフになりました

この「邪悪な吸引力」を備えたこの250ドルのハンドヘルド掃除機は、Amazonで75%オフになりました

多くのAmazonの買い物客がUmlo H6ハンドヘルド掃除機を推奨しており、現在スーパーセール中です. ハンドヘルド デバイスには HEPA フィルターが装備されており、複数のアタッチメントが付属しています。Amazonで75%オフのときにハンドヘルド掃除機を購入する

オクタヴィア・スペンサー、「ザ・ヘルプ」共演者のシシー・スペイセクが17歳で映画のインターンをした後、彼女のことを「実際に」思い出したと語る

オクタヴィア・スペンサー、「ザ・ヘルプ」共演者のシシー・スペイセクが17歳で映画のインターンをした後、彼女のことを「実際に」思い出したと語る

オクタヴィア・スペンサーは、ヘルプで一緒に共演するずっと前に、シシー・スペイセク主演の 1990 年の映画「ロング・ウォーク・ホーム」でインターンとして働いていました。

ジュリア・フォックス、「マスカラ」がTikTokユーザーの性的暴行コードだったことを知らなかったことを謝罪

ジュリア・フォックス、「マスカラ」がTikTokユーザーの性的暴行コードだったことを知らなかったことを謝罪

ジュリア・フォックスは、彼女のTikTokで共有された応答ビデオで、「本当に申し訳ありません。今、本当に年齢を示しています」と述べました。

メリック・ガーランドはアメリカに失敗しましたか?

バイデン大統領の任期の半分以上です。メリック・ガーランドは何を待っていますか?

メリック・ガーランドはアメリカに失敗しましたか?

人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。

良いものと醜いもの: 2022

良いものと醜いもの: 2022

もうわからない。何が「ヒット」かを正確に判断することは、もはやほとんど不可能に思えます。

楽しみのために — 2022 年のトップの新しい音楽再生

楽しみのために — 2022 年のトップの新しい音楽再生

ついに!私の 2022 年のトップ ニューミュージック プレイへようこそ。私は毎年これを共有して、友達とつながります。

ヒーズ・オール・アイヴ・ガット

ヒーズ・オール・アイヴ・ガット

あなたの心をチェックしてください。私たちの心はしばしば迷います。

Language