如何将 NSInteger 转换为 NSUInteger?

25

我想将一个 NSInteger 转换为 NSUInteger,但在谷歌上搜寻并没有找到真正的答案。请问我应该如何做?

4个回答

36

NSIntegerNSUInteger 只是原始整数类型的 typedef 别名:

#if __LP64__ || NS_BUILD_32_LIKE_64
  typedef long NSInteger;
  typedef unsigned long NSUInteger;
#else
  typedef int NSInteger;
  typedef unsigned int NSUInteger;
#endif

因此,你不需要在它们之间进行“转换”。只需进行简单的强制类型转换即可。像这样:

NSInteger myInt = 0;
NSUInteger unsignedInt = (NSUInteger)myInt;

5
将有符号整数转换为无符号整数是否存在安全隐患?我读到过这可能会导致数据损坏,因为在无符号整数中,符号位可能被解释为一个值?或者C语言可以避免这种情况发生? - Constantino Tsarouhas

8

以下是一个小表格,展示了强制类型转换的实际效果,希望对其他遇到此问题的人有所帮助。这些值直接从调试器中以十六进制的形式获取。根据需要进行选择,因为可以看出强制类型转换确实会产生效果。对于32位,去掉底部的ffffffff,对于16位,去掉底部的ffffffffffff。还要注意,-1始终为0xffffffffffffffff。

NSInteger si = NSIntegerMax;    // si   NSInteger   0x7fffffffffffffff
si = -1;                        // si   NSInteger   0xffffffffffffffff
si = (NSInteger)-1;             // si   NSInteger   0xffffffffffffffff
si = (NSUInteger)-1;            // si   NSInteger   0xffffffffffffffff
si = NSUIntegerMax;             // si   NSInteger   0xffffffffffffffff
si = (NSInteger)NSIntegerMax;   // si   NSInteger   0x7fffffffffffffff
si = (NSUInteger)NSIntegerMax;  // si   NSInteger   0x7fffffffffffffff
si = (NSInteger)NSUIntegerMax;  // si   NSInteger   0xffffffffffffffff
si = (NSUInteger)NSUIntegerMax; // si   NSInteger   0xffffffffffffffff

NSUInteger ui = NSUIntegerMax;  // ui   NSUInteger  0xffffffffffffffff
ui = -1;                        // ui   NSUInteger  0xffffffffffffffff
ui = (NSInteger)-1;             // ui   NSUInteger  0xffffffffffffffff
ui = (NSUInteger)-1;            // ui   NSUInteger  0xffffffffffffffff
ui = NSIntegerMax;              // ui   NSUInteger  0x7fffffffffffffff
ui = (NSInteger)NSIntegerMax;   // ui   NSUInteger  0x7fffffffffffffff
ui = (NSUInteger)NSIntegerMax;  // ui   NSUInteger  0x7fffffffffffffff
ui = (NSInteger)NSUIntegerMax;  // ui   NSUInteger  0xffffffffffffffff
ui = (NSUInteger)NSUIntegerMax; // ui   NSUInteger  0xffffffffffffffff

4

如果您确定您的NSInteger大于或等于零,您只需将其转换为NSUInteger。如果您的NSInteger表示负数,则不应将其强制转换为NSUInteger,因为这可能会导致不一致性。

NSInteger signedInteger = -30;
NSUInteger unsignedInteger = (NSUInteger)signedInteger;

导致

整数结果

if (unsignedInteger == signedInteger) {
    // is TRUE
}
if (signedInteger == 4294967266) {
    // is FALSE
}
if (signedInteger == -30) {
    // is TRUE
}
if (unsignedInteger == 4294967266) {
    // is TRUE
}
if (unsignedInteger == -30) {
    // is TRUE
}

在 NSObjCRuntime.h 中: #define NSUIntegerMax ULONG_MAX NSLog(@"ULONG_MAX: %lu", ULONG_MAX); ULONG_MAX: 4294967295 4294967295-30+1 = 4294967266+1 是因为:NSInteger ui = NSIntegerMax; ui = -1; ui = (NSUInteger)-1; - Dmitrii Cooler

0
如果您想将整数转换为无符号整数,那么您可能处于以下两种情况之一:要么您知道该整数永远不会为负数,要么您希望所有负值都被转换为绝对值(即无符号值)。将其转换为绝对值非常简单:
NSInteger mySignedInteger = -100;
NSUInteger myUnsignedInteger = fabs(mySignedInteger);

fabs() 是一个 C 函数,用于返回任何浮点数的绝对值。在这里,myUnsignedInteger 的值将为 100。

这样的函数可能有多种用途,例如在显示中指示负值的不同格式。例如,在会计中,负数以括号形式显示:

NSString * numberForDisplay;
if (mySignedInteger < 0) {
    numberForDisplay = [NSString stringWithFormat:@"(%lu)", myUnsignedInteger];
} else {
    numberForDisplay = [NSString stringWithFormat:@"%lu", myUnsignedInteger];
}

请注意,从技术角度来看,您可以将NSInteger简单地分配给NSUInteger – 这甚至不需要转换,但当NSInteger为负数时,NSUInteger将返回一个非常大的正数,这显然是一个非常不希望的副作用。
NSUInteger myUnsignedInteger = mySignedInteger;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接