【问题标题】:Convert NSInteger to NSUInteger?将 NSInteger 转换为 NSUInteger?
【发布时间】:2011-08-07 05:38:10
【问题描述】:

我正在尝试将 NSInteger 转换为 NSUInteger,但我用谷歌搜索并没有找到真正的答案。我该怎么做?

【问题讨论】:

    标签: objective-c nsinteger nsuinteger


    【解决方案1】:

    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;
    

    【讨论】:

    • 将有符号整数转换为无符号整数是否危险?我读到它可能会导致损坏,因为符号位可能被解释为无符号整数中的值?还是 C 做了所有的工作来防止这种情况发生?
    【解决方案2】:

    由于这可能对遇到此问题的其他人有用,因此这里有一个小表格,向您展示投射的实际效果。这些值是直接从调试器中获取的十六进制值。相应地选择,如您所见,铸造确实会产生影响。对于 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
    

    【讨论】:

      【解决方案3】:

      如果您确定您的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
      }
      

      【讨论】:

      • in 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;
      【解决方案4】:

      如果您想将整数转换为无符号整数,您要么知道整数永远不会是负数,要么您可能希望将所有负值转换为绝对值(即,无符号值)。将此转换为绝对值很简单:

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-21
        • 2012-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多