编辑:我将示例更新为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
数据类型而不是整数数据类型,但对于我的目的,整数数据类型更容易使用和管理。
答案 0 :(得分:2)
将有符号整数转换为无符号整数的安全方法,同时始终在转换之间保持完全相同的位模式
即使union
是罕见的非2补码,int
也会如下工作。只有在非常期待的平台上(在硅墓地中嘀嗒一声)INT_MAX == UINT_MAX
这将是一个问题。
union {
int i;
unsigned u;
} x = { some_int };
printf("%d\n", some_int);
printf("%u\n", x.u);
然而,如果一个人可以将自己限制在共同的2的补语int
,那么下面就足够了。
unsigned u = (unsigned) some_int;
但是像OR这样的位运算符呢(下面的情况B)? 可以按比特使用OR来安全地将signed转换为unsigned吗?
由于整数促销,以下|
就像一个隐藏的演员:
如果
int
可以表示原始类型的所有值(受宽度限制,对于位字段),则该值将转换为int
;否则,它将转换为unsigned int
。 C11dr§6.3.1.13
int s1 = -3730470;
unsigned int u1b = (unsigned int)0 | s1;
// just like
= (unsigned int)0 | (unsigned int)s1;
= (unsigned int)s1;
反过来呢?
如果unsigned int
中的值可以表示,则可以很好地定义signed int
到[0...INT_MAX]
。将int
范围unsigned
范围int
转换为// NOTE: assuming 32bit ints, etc.
unsigned int u2 = 4291236826;
int s2a = (int)u2; // avoid this
是......
结果是实现定义的,或者引发实现定义的信号。 §6.3.1.33
最好使用无符号类型进行位操作 以下代码通常可以按预期工作,但不应用于强大的编码。
int s2a;
if (u2 > INT_MAX) {
// Handle with some other code
} else {
s2a = (int) u2; // OK
}
替代
u
BTW:最好将long long
附加到无符号常量,如4291236826,以便向编译器传达确实无符号常量而不是{{1像4291236826。
unsigned int u2 = 4291236826u;
答案 1 :(得分:0)
那......
| USID | Date | Utilized | RowNumber |
|------|----------------------|----------|-----------|
| 123 | 2019-01-01T00:00:00Z | T | 1 |
| 123 | 2019-01-02T00:00:00Z | T | 2 |
| 123 | 2019-01-03T00:00:00Z | T | 3 |
| 123 | 2019-01-04T00:00:00Z | F | 1 |
| 123 | 2019-01-05T00:00:00Z | F | 2 |
| 123 | 2019-01-06T00:00:00Z | F | 3 |
| 123 | 2019-01-07T00:00:00Z | F | 4 |
| 123 | 2019-01-08T00:00:00Z | F | 5 |
| 123 | 2019-01-09T00:00:00Z | F | 6 |
| 123 | 2019-01-19T00:00:00Z | T | 1 |
| 123 | 2019-01-20T00:00:00Z | T | 2 |
| 123 | 2019-01-21T00:00:00Z | T | 3 |
| 223 | 2019-01-01T00:00:00Z | T | 1 |
| 223 | 2019-01-02T00:00:00Z | T | 2 |
| 223 | 2019-01-03T00:00:00Z | T | 3 |
| 223 | 2019-01-04T00:00:00Z | F | 1 |
| 223 | 2019-01-05T00:00:00Z | F | 2 |
| 223 | 2019-01-06T00:00:00Z | F | 3 |
| 223 | 2019-01-07T00:00:00Z | F | 4 |
| 223 | 2019-01-08T00:00:00Z | F | 5 |
| 223 | 2019-01-09T00:00:00Z | F | 6 |
| 223 | 2019-01-19T00:00:00Z | T | 1 |
| 223 | 2019-01-20T00:00:00Z | T | 2 |
| 223 | 2019-01-21T00:00:00Z | T | 3 |