編輯:我更新了示例爲C.我特別關心C而不是C++(對於混淆,請參閱下面的情況)。C轉換籤名爲無符號維持精確位
我正在尋找一種安全的方法來將有符號整數轉換爲無符號整數,同時始終保持轉換之間完全相同的位模式。據我所知,簡單地說,鑄造具有未定義的或依賴於實施的行爲,因此依靠它是不安全的(下面的情況A)。但是像OR這樣的按位運算符(下面的情況B)呢?可以按位或用於安全地將簽名轉換爲無符號?那反過來呢?
實施例:
#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);
}
情況:我寫一個PostgreSQL C-Language function /分機來增加popcount功能(my first attempt code here)。 PostgreSQL不支持無符號類型(ref)。計算popcount的所有有效方法都要求無符號數據類型正常工作。因此,我必須能夠將簽名數據類型轉換爲無符號數據類型,而不改變位模式。
題外話:我也知道一個替代的解決辦法是使用PostgreSQL位串bit
和varbit
數據類型,而不是整數數據類型的,但我的目的是整型數據類型更容易使用和管理。
使用「聯合」來保持精確的位。 「簡單地說,鑄造具有未定義或依賴於實現的行爲,因此依賴它並不安全」並非如此。 – chux
代碼似乎是C++,但問題被標記爲C .... –
請記住,有符號位表示是實現定義的。所以顯然它會在不同的平臺上表現不同。 –