編集:私はこの例をC言語に更新しました。特にC++ではなく、C++ではありません(以下の状況を参照してください)。C符号付きを符号なしに維持する正確なビット
私はいつも変換の間の正確な同じビットパターンを維持しながら、符号なし整数への符号付き整数に変換する安全な方法を探しています。私が理解しているように、単にキャストすることは定義されていないか、または実装に依存するため、依存するのは安全ではありません(以下のケースA)。しかし、ORのようなビットワイズ演算子(以下のケースB)はどうでしょうか?ビット単位でORを使用して、符号付きから符号なしに安全に変換できますか?その逆はどうですか?
例:
#include <stdio.h>
int main() {
// NOTE: assuming 32bit ints
// example bit pattern: 11111111110001110001001111011010
// signed int value: -3730470
// unsigned int value: 4291236826
// example 1
// signed -> unsigned
int s1 = -3730470;
unsigned int u1a = (unsigned int)s1;
unsigned int u1b = (unsigned int)0 | s1;
printf("%u\n%u\n", u1a, u1b);
// example 2
// unsigned -> signed
unsigned int u2 = 4291236826;
int s2a = (int)u2;
int s2b = (int)0 | u2;
printf("%i\n%i\n", s2a, s2b);
}
状況:私はPOPCOUNT機能(my first attempt code here)を追加するPostgreSQL C-Language function /拡張を書いています。 PostgreSQLは、符号なしタイプ(ref)をサポートしていません。私が見つけたpopcountを計算するすべての効率的な方法は、符号なしデータ型が正しく機能することを要求します。したがって、ビットパターンを変更することなく、符号付きデータ型を符号なしデータ型に変換できなければなりません。オフトピック
:私は別の解決策ではなく、整数データ型のPostgreSQLのビット列bit
とvarbit
データ型を使用することであろうことを認識しますが、私の目的のために整数データ型を使用して管理する方がはるかに簡単です。
正確なビットを維持するために 'union 'を使用してください。 「単純にキャストに未定義または実装に依存する動作があるため、依存しても安全でない」ということは、「符号なし」には向かない。 – chux
コードはC++で表示されますが、質問にはタグが付けられています。 –
符号付きビット表現は実装定義です。したがって、明らかに異なるプラットフォームでは動作が異なります。 –