Question

J'ai rencontré un bogue dans un code C que j'ai écrit, et bien qu'il soit relativement facile à corriger, je veux être en mesure de mieux comprendre le problème qui le sous-tend. Essentiellement, ce qui s'est passé, c'est que j'ai eu deux entiers non signés (Uint32_T, en fait) que, lorsque l'opération de module a été appliquée, a donné l'équivalent non signé d'un nombre négatif, un nombre qui avait été enveloppé et était donc "grand". Voici un exemple de programme à démontrer:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char* argv[]) {

  uint32_t foo = -1;
  uint32_t u   = 2048;
  uint64_t ul  = 2048;

  fprintf(stderr, "%d\n", foo);
  fprintf(stderr, "%u\n", foo);
  fprintf(stderr, "%lu\n", ((foo * 2600000000) % u));
  fprintf(stderr, "%ld\n", ((foo * 2600000000) % u));
  fprintf(stderr, "%lu\n", ((foo * 2600000000) % ul));
  fprintf(stderr, "%lu\n", foo % ul);

  return 0;

}

Cela produit la sortie suivante, sur ma machine x86_64:

-1
4294967295
18446744073709551104
-512
1536
2047

1536 est le numéro que j'attendais, mais (uint32_t) (- 512) est le numéro que j'obtenais, ce qui, comme vous pouvez l'imaginer, a un peu jeté les choses.

Donc, je suppose que ma question est la suivante: pourquoi une opération de module entre deux nombres non signés, dans ce cas, produit-il un nombre supérieur au diviseur (c'est-à-dire un nombre négatif)? Y a-t-il une raison pour laquelle ce comportement est préféré?

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top