2011-04-27 32 views
1

有什么办法来探测一个NSNumber,看看它是一个int或unsigned int。我试图用objCType来做到这一点,但我无法分辨。考虑以下情形:NSNumber类方法可以识别signed和unsigned int吗?

NSNumber *number1 = [NSNumber numberWithUnsignedInt:100]; 
NSNumber *number2 = [NSNumber numberWithInt:100]; 

NSLog(@"%@",[NSString stringWithUTF8String:[number1 objCType]]); 
NSLog(@"%@",[NSString stringWithUTF8String:[number2 objCType]]); 

输出: 我 我

是否有任何人知道如何解决这个问题呢?

回答

2

objCType并不能保证它返回的类型将是一样的,你投入的类型。

什么你想要做的基本上忽略了NSNumber点,这是为了避免与笨拙这些数值需要用C来处理。通过在NSNumber中包含数值,您可以将它与任何其他此类值进行比较,而不考虑它们的“实际”(按位)类型,并且可以将值返回到一个不同的“实际”类型比你开始。*

它不会给你回完全相同的类型,因为它不需要 - 你把任何你想要拿出你想要的东西。无论如何,运行时C变量的类型是未知的。

我想你必须使用NSNumber,因为你需要将数值粘贴到Cocoa集合中?您可能必须将NSNumber包装在您自己的对象中,该对象也会保留初始类型的记录。这将需要很长的switch或一堆if/else小号...


*这里唯一需要注意的是,现在你必须再次与类型的大小有关:试图把一个值例如,比FLT_MAX更大的一个float会给你带来垃圾。

2

为什么这是一个问题?

NSNumber,简单地说,不在乎数字是无符号还是有符号的,并且会根据需要强制或转换;就像它不关心数字是固定还是浮点一样。

数字的类型只在创作时才有意义。

+0

我有一个程序,我知道这是在创作什么类型的号码。但我可能以后访问这个号码,我需要知道如何在访问时输入它。如果你能想到更优雅的做法,我愿意提出建议。 – banDedo 2011-04-27 22:10:31

2

号引擎盖下NSNumber使用CFNumber,而后者不存储的无符号值 - 该方法的NSNumber检查传入的值,如果它过大,以适应在已签名的类型相同大小的它使用下一个较大的签名类型(是的,如果你存储一个大的无符号64位整数NSNumber使用一个内部128位有符号整数。)

如果你想跟踪原始类型,你必须自己做,创建一个类型字段和数字字段的对象...

1

您可以使用类别扩展NSNumber

@implements NSNumber (Signed) 
    - (BOOL)isNumberSigned { 
     // Test if number less than zero 
     // return the result 
    } 

这就是Objective-C的美感;延长课程非常简单。

0

使用[- doubleValue][- stringValue][- decimalValue]可以揭示在使用带符号的init方法创建时原始值是否为负值。 我很惊讶没有简单的- wasCreatedSigned功能。

BOOL negTest; 
negTest = ([myNSNumber doubleValue] < 0);     // <0.1 micro sec 
negTest = [[myNSNumber stringValue] hasPrefix:@"-"];  // >1.5 micro sec 
negTest = ([myNSNumber decimalValue]._isNegative);  // >2.5 micro sec 
negTest = ([myNSDecimalNumber decimalValue]._isNegative); // <0.1 micro sec 

内部NSNumber IS知道其值的签名状态。

至于-objCType我注意到它并不总是反映init类型,如文档所述。但它会准确区分花车/双打(d)远离整数(c,s,i,q,Q ...)。

下面是一些代码一起玩,它就会发现有些古怪的地方(在iOS 4.3测试):

void isNeg(NSNumber* num, NSString* initMethod); 
void isNeg(NSNumber* num, NSString* initMethod) 
{ 
    printf("\r"); 
    NSLog(@"%@ (class:%@)", initMethod, [num class]); 

    double dval = [num doubleValue]; 
    NSLog(@"Is Negative:%c, objCType:%s", (dval<0)?'Y':'N', [num objCType]); 
    NSLog(@"strVal: %@", [num stringValue]); 
    NSLog(@"%%f : %f", dval); 
    NSLog(@"%%g : %g", dval); 
    NSLog(@"%%lld : %lld", [num longLongValue]); 
    NSLog(@"%%llu : %llu", [num unsignedLongLongValue]); 
} 

// main... 
double testDouble = 10001e-9; 
Class nc = [NSNumber class]; 

isNeg([nc numberWithChar: -1], @"Char"); 
isNeg([nc numberWithChar: -2], @"Char"); 
isNeg([nc numberWithChar: -3], @"Char"); 
isNeg([nc numberWithChar:  1], @"Char"); 
isNeg([nc numberWithChar: 12], @"Char"); 
isNeg([nc numberWithChar: 13], @"Char"); 
isNeg([nc numberWithUnsignedChar: 12], @"UChar"); 
isNeg([nc numberWithUnsignedChar: 13], @"UChar"); 

isNeg([nc numberWithLongLong:  -LONG_LONG_MAX], @"LongLong"); 
isNeg([nc numberWithLongLong:   LONG_LONG_MAX], @"LongLong"); 
isNeg([nc numberWithUnsignedLongLong: ULONG_LONG_MAX], @"ULongLong"); 

isNeg([nc numberWithDouble:-LONG_LONG_MAX], @"Double"); 
isNeg([nc numberWithDouble: ULONG_LONG_MAX], @"Double"); 

isNeg([nc numberWithDouble:-testDouble], @"Double"); 
isNeg([nc numberWithDouble: testDouble], @"Double"); 

nc = [NSDecimalNumber class]; 
isNeg([nc numberWithDouble:-testDouble], @"Double"); 
isNeg([nc numberWithDouble: testDouble], @"Double"); 
相关问题