8

の形式で一意のIDunsigned long intを作成するアプリがあります。アプリにはこの精度が必要です。

ただし、 sのみを許可するプロトコルでこれらのIDintを送信する必要があります。プロトコルの受信アプリケーションは、この精度を必要としません。だから私の質問は次のとおりです。特にが より大きい場合、どうすれunsigned long intばを に変換できますか?intunsigned long intint

編集:

プロトコルint. _ 「ロールオーバーの問題」を回避する方法を知っておくとよいでしょう

メッセージを送信するアプリケーションは、長期間にわたって一意性を知る必要がありますが、受信者は一意性を短時間だけ知る必要があります。

4

6 に答える 6

14

考えられるアプローチの 1 つを次に示します。

#include <climits>
unsigned long int uid = ...;
int abbreviated_uid = uid & INT_MAX;

たとえばint、 が 32 ビットの場合、これは UID の下位 31 ビットを除くすべてを破棄します。負でない値のみが生成されます。

これにより、元の から情報が失われuidますが、それは問題ではないことを示しました。

しかし、あなたの質問は非常に漠然としているため、これがあなたの目的に合っているかどうかを判断するのは困難です.

于 2012-07-08T23:01:55.237 に答える
3

ブーストはnumeric_cast

unsigned long l = ...;
int i = boost::numeric_cast<int>(l);

変換がオーバーフローする場合、これは例外をスローします。これは、希望するものである場合とそうでない場合があります。

于 2012-07-08T23:46:22.513 に答える
3

Keith Thompson の「& INT_MAX」は、abbreviated_uid が負でないことを確認する必要がある場合にのみ必要です。それが問題ではなく、負の ID を許容できる場合 は、単純なキャスト (C スタイルまたは static_cast()) で十分ですsizeof(unsigned long int)==sizeof(int)。受信側でキャストバックするunsigned long intと、送信側と同じ値になります)。

受信者は ID に関する応答を送信者に送り返しますか? 元の送信者 (応答の受信者) はこれを元のunsigned long intID と一致させる必要がありますか? その場合は、応答を元の ID と照合するための追加のロジックが必要になります。もしそうなら、そのような要件を示す編集を投稿してください。私 (または他の人) はその問題に対処する方法を提案できます。この問題の 1 つの考えられる解決策は、ID を複数のint部分に分割し、反対側でまったく同じunsigned long int値に再構築することです。それについて助けが必要な場合は、私または他の誰かがそれを手伝うことができます.

于 2012-07-08T23:54:07.933 に答える
3

ご存知のように、一般的なケースでは、理論上安全に を に変換することはできませunsigned long intint。しかし、整数があまり大きくない多くの実用的なケースでは実際にそうすることができます。

私はおそらくこれを定義して使用します:

struct Exc_out_of_range {};

int make_int(const unsigned long int a) {
    const int n = static_cast<int>(a);
    const unsigned long int a2 = static_cast<unsigned long int>(n);
    if (a2 != a) throw Exc_out_of_range();
    return n;
}

ヘッダーを使用した同等のソリューション<limits>は当然可能ですが、上記よりも優れているかどうかはわかりません。(コードがタイム クリティカルなループにあり、移植性が重要でない場合は、アセンブリでコーディングして、関心のあるビットまたはビットを直接テストできますが、アセンブリ言語での演習を除いて、これは面倒です。)

パフォーマンスに関しては、コンパイラが非常に古いものでない限り、throw使用しない限り実行時の負荷がかからないことに注意してください。

@GManNickG は、から継承するアドバイスを追加しstd::exceptionます。私は個人的にこれについて強い感情を持っていませんが、アドバイスは十分に根拠があり、高く評価されており、従わない理由はほとんどないと思います. このような継承の詳細については、こちらを参照してください。

于 2012-07-08T23:18:32.793 に答える
-1

あなたは使用しようとすることができstd::stringstreamますatoi()

#include <sstream>
#include <stdlib.h>
unsigned long int a = ...;
std::stringstream ss;
ss << a;
std::string str = ss.str();
int i = atoi(str.c_str());
于 2016-09-24T13:31:24.810 に答える