Strano conversione da NSUInteger a carri
-
25-09-2019 - |
Domanda
Ho il seguente codice:
NSUInteger one = 1;
CGPoint p = CGPointMake(-one, -one);
NSLog(@"%@", NSStringFromCGPoint(p));
La sua uscita:
{4.29497e+09, 4.29497e+09}
D'altra parte:
NSUInteger one = 1;
NSLog(@"%i", -one); // prints -1
So che probabilmente c'è un qualche tipo di troppo pieno in corso, ma perché i due casi sono diversi e perché non funziona come voglio? Devo sempre ricordare a me stesso di particolare tipo numerico delle mie variabili ed espressioni anche quando si fa aritmetica banali?
P.S. Naturalmente potrei usare unsigned int
invece di NSUInteger
, non fa differenza.
Soluzione
Quando si applica il -
unario per un valore senza segno, il valore non firmato è negato e poi costretto a tornare in abito firmato da avere Utype_MAX + 1
ripetutamente aggiunto a tale valore. Quando si passa a quella CGPointMake()
, che (molto grande) valore senza segno viene quindi assegnato a un CGFloat
.
Non vedo questo nella sua dichiarazione NSLog()
perché si accede come un intero con segno. Convertire che di nuovo ad un numero intero con segno ed è in effetti ottiene -1. Provare a utilizzare NSLog("%u", -one)
e troverete sei di nuovo a destra al 4294967295
.
unsigned int
contro NSUInteger
fa la differenza: unsigned int
è grande la metà di NSUInteger
sotto un'architettura LP64 (x86_64, ppc64) o quando si compila con NS_BUILD_32_LIKE_64
definito. NSUInteger
sembra essere sempre puntatore di dimensioni (ma l'uso uintptr_t
se si ha realmente bisogno di un numero intero che è la dimensione di un puntatore!); unsigned
non è quando si utilizza il modello LP64.
Altri suggerimenti
OK senza realmente sapere, ma leggendo in giro in rete su tutti questi tipi di dati, direi che il problema è stato con la conversione da un NUSInteger (che risolve sia ad un int (x32) o una lunga (x64)) ad un CGFloat (che risolve sia un galleggiante (x32) o doppia (x64)).
Nel vostro secondo esempio che stessa conversione non sta accadendo. L'altra cosa che può essere effettuando è che dalla mia lettura, NSUinteger non è progettato contiene numeri negativi, ma solo quelli positivi. In modo che è probabile che sia dove le cose iniziano ad andare male.