36 votes

Que signifie "int i = 1;Why (i >= 60 * 60 * 1000 / 1 * 1000)" ?

D'abord, définir deux expressions constantes sans parenthèses est ma faute :

#define BIG_INTERVAL 60 * 60 * 1000
#define SMALL_INTERVAL 1 * 1000

int i = 1;

if (i >= BIG_INTERVAL / SMALL_INTERVAL - 1)
{
    printf("Oops!\n");
}

En if après l'expansion de la macro est if(i >= 60 * 60 * 1000 / 1 * 1000 - 1) .

Ce n'est pas mon intention. Mais je trouve quelque chose d'étrange si j'écris if (i >= 3600000000 - 1) . C'est faux.

Quel type est 60 * 60 * 1000 / 1 * 1000 - 1 ? int ?

69voto

dan04 Points 33306

Tous les opérateurs sur int s retour int . Alors oui, 60 * 60 * 1000 / 1 * 1000 - 1 est un int . Mais le résultat attendu de 3599999999 est trop grand pour une int L'expression est donc évaluée à -694967297 (en supposant que l'on utilise le format 32 bits). int et complément à deux).

Cela ne se produit pas avec un littéral 3600000000 parce que les littéraux entiers plus grands que INT_MAX sont d'un type qui peut retenir la valeur totale.

42voto

Petar Ivanov Points 29530

60 * 60 * 1000 / 1 * 1000 - 1 = 3600000 * 1000 - 1, ce qui dépasse le type int, donc le résultat peut être n'importe quoi (dans votre cas, il est négatif, mais ce n'est pas obligatoire).

Pour obtenir ce que vous voulez, mettez ( ) :

#define BIG_INTERVAL (60 * 60 * 1000)
#define SMALL_INTERVAL (1 * 1000)

12voto

dpp Points 4938

Voici les résultats de mes tests :

60 * 60 * 1000 / 1 * 1000 will result to -694967296

(60 * 60 * 1000) / (1*1000) will result to 3600

Il y a un problème avec votre opération, la préséance des calculs.

Vous pourriez envisager de regarder la précédence des opérateurs en C++. http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.80%29.aspx . Vous trouverez la raison pour laquelle le résultat est devenu -694967296 qui, je pense, est un effet de débordement.

9voto

Windows programmer Points 5365

Si vous utilisez un compilateur où int est 64 bits, vous constaterez que le résultat de votre expression est faux. Si vous utilisez un compilateur où int est 32 bits ou 16 bits, votre expression a un comportement indéfini parce que le débordement des ints signés n'a pas besoin de s'enrouler. Probablement que la vôtre s'est enroulée, mais elle n'est pas obligée de le faire.

3600000000 est une constante visible au moment de la compilation, donc si int n'a que 32 bits, votre compilateur devra choisir long long (ou juste long si long a 64 bits). Ainsi, votre autre expression est évaluée avec suffisamment de bits pour éviter le débordement, et le résultat est correct.

4voto

Jesus Ramos Points 15798

Il se peut que vous dépassiez la taille d'un int, qui est de 2147m ou plus, signé, ce qui signifie que si vous dépassez la représentation pour cela devient négative. Comme indiqué par d'autres réponses, la division ne fait rien quand elle est étendue, donc il faut entourer les définitions de macro entre parenthèses.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X