2011-08-07 3 views

Répondre

32

NSInteger et NSUInteger sont juste typedefs pour les types entiers primitifs:

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

En tant que tel, vous n'avez pas besoin de "convertir" entre eux. Un simple casting devrait être suffisant. Comme:

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

Gratzi, votre deuxième petit peu de code là a fonctionné pour moi! –

+3

Est-ce que la conversion d'un int signé en un entier non signé n'est pas dangereuse? J'ai lu que cela peut causer de la corruption comme un bit de signe peut être interprété comme une valeur dans ints non signé? Ou tout le travail pour empêcher cela? –

8

Comme cela pourrait être utile pour d'autres qui rencontrent ce problème, voici une petite table vous montrant l'effet réel de la coulée. Ces valeurs ont été extraites directement du débogueur en tant que valeurs hexadécimales. Choisissez en conséquence, car vous pouvez voir que le lancer cause des effets. Pour 32 bits, coupez le bas ffffffff et pour 16 bits lop off ffffffffffff. Notez également que -1 est toujours 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

Si vous êtes certain que votre NSInteger est supérieure ou égale à zéro, vous lancez simplement comme NSUInteger. Vous ne devriez pas utiliser NSUInteger si votre NSInteger représente un nombre négatif, car cela peut entraîner des incohérences.

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

résultats dans

integer results

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 
} 
+0

dans NSObjCRuntime.h '#define NSUIntegerMax ULONG_MAX' ' NSLog (@ "ULONG_MAX:% ld", ULONG_MAX);' ' ULONG_MAX: 4294967295' 4294967295-30 + 1 = 4294967266 1 en raison de ' NSInteger ui = NSIntegerMax; '' ui = -1; '' ui = (NSUInteger) -1; ' –

0

Si vous êtes désireux de convertir un nombre entier à un entier non signé, vous êtes soit dans une situation où vous savez que l'entier ne sera jamais négatif ou vous pouvez souhaiter que toutes les valeurs négatives soient converties en valeurs absolues (c'est-à-dire des valeurs non signées). Faire cette conversion à une valeur absolue est simple:

NSInteger mySignedInteger = -100; 
NSUInteger myUnsignedInteger = fabs(mySignedInteger); 

fabs() est une fonction C qui retourne une valeur absolue pour tout flotteur. Ici, myUnsignedInteger aurait la valeur 100.

Les cas d'utilisation possibles pour une telle fonction seraient l'affichage où vous indiquerez les valeurs négatives dans un format différent. Par exemple, en nombres négatifs comptables sont affichés entre parenthèses:

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

Notez que d'un point de vue technique, vous pouvez simplement attribuer un NSInteger à un NSUInteger-cela ne nécessite même pas un casting, mais lorsque le NSInteger est négatif le NSUInteger retournera un très grand nombre positif, ce qui est clairement un effet secondaire très indésirable:

NSUInteger myUnsignedInteger = mySignedInteger; 
Questions connexes