2016-03-23 2 views
1

J'essaie quelque chose sur mon Mac OS X XCode 7.2.1 -un comportement inattendu unsigned long long dans le compilateur Xcode clang

#define uint64 unsigned long long 

int N = 100000; 
uint64 value = (pow(N, 4) + 2 * pow(N, 3) + 3 * pow(N, 2) + 2 * N)/4; 
cout << "value: " << value << endl; // this is equivalent to ULLONG_MAX (18446744073709551615) 
cout << "ULLONG_MAX: " << ULLONG_MAX << endl; 

Ainsi, la sortie est censé être -

value: 18446744073709551615 
ULLONG_MAX: 18446744073709551615 

Mais la la sortie est -

value: 0 
ULLONG_MAX: 18446744073709551615 

Les changements ci-dessous n'ont pas fait de différence.

uint64 N = 100000ull; 
uint64 value = (pow(N, 4ull) + 2ull * pow(N, 3ull) + 3ull * pow(N, 2ull) + 2ull * N)/4ull; 

exécution gcc --version commande sur mes rendements terminaux -

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 7.0.2 (clang-700.1.81) 
Target: x86_64-apple-darwin15.0.0 
Thread model: posix 

J'ai essayé code ci-dessus dans HackerRank g ++ 4.9.2 compilateur et la sortie était correcte.

Que se passe-t-il sous le capot? Est-ce Clang ou mon OS (Mac OS X 10.11)?

+2

Si vous affectez à 'long double' à la place, vous verrez que le résultat est _not_' ULLONG_MAX'. Au lieu de cela, il déborderait. 'long double valeur = pow (N, 4.0L) + 2.0L * pow (N, 3.0L) + 3.0L * pow (N, 2.0L) + 2.0L * N)/4.0L;' – paddy

+0

Merci :) 'long double' peut contenir plus de données, ce qui est certainement utile pour vérifier si un débordement se produit dans ce cas. –

Répondre

4

Ceci est dû à un débordement. Votre équation retourne: 25000500007500050000 qui est trop grand pour un long non signé.

Il semblerait que clang gère cela différemment de g ++. J'ai fait un petit test pour voir ce que le résultat est devenu après le casting.

Voir: Clang giving random values tandis que g++ renvoie std::numeric_limits<std::uint64_t>::max().


Si vous avez besoin ce nombre (dans un type de données) Je vous conseille personnellement de trouver une bibliothèque qui prend en charge les numéros de longueur arbitraire (gmp ou comparables).

+1

Merci. J'ai deviné presque la même chose que vous, juste heureux d'en être sûr :) Spécialement pour mon problème, la manipulation avec 'unsigned long long' a passé tous les cas de test donc je n'aurai pas besoin de faire face à un grand nombre entier ou similaire temps. –