Vous avez déjà la puce réponse: non signé de l'arithmétique modulo arithmétique et, par conséquent, les résultats seront en attente, vous pouvez le prouver mathématiquement...
Une chose cool à propos des ordinateurs, cependant, est que les ordinateurs sont rapides. En effet, ils sont si rapides que l'énumération de toutes les combinaisons valides de 32 bits est possible dans un laps de temps raisonnable (ne pas essayer avec la version 64 bits).
Donc, dans votre cas, personnellement, j'aime juste le jeter à un ordinateur; il me prend moins de temps à me convaincre que le programme est correct qu'il n'en faut pour me convaincre que la preuve mathématique est correct et que je n'ai pas de superviser un détail dans le cahier des charges1:
#include <iostream>
#include <limits>
int main() {
std::uint64_t const MAX = std::uint64_t(1) << 32;
for (std::uint64_t i = 0; i < MAX; ++i) {
for (std::uint64_t j = 0; j < MAX; ++j) {
std::uint32_t const a = static_cast<std::uint32_t>(i);
std::uint32_t const b = static_cast<std::uint32_t>(j);
auto const champion = (a + (b & 255)) & 255;
auto const challenger = (a + b) & 255;
if (champion == challenger) { continue; }
std::cout << "a: " << a << ", b: " << b << ", champion: " << champion << ", challenger: " << challenger << "\n";
return 1;
}
}
std::cout << "Equality holds\n";
return 0;
}
Cette énumère toutes les valeurs possibles de l' a
et b
dans le 32 bits de l'espace et vérifie si l'égalité tient ou pas. Si elle ne le fait pas, il imprime les cas qui n'ont pas de travail, que vous pouvez utiliser comme un test de cohérence.
Et, selon Clang: l'Égalité détient.
En outre, étant donné que les règles arithmétiques sont des bits de largeur agnostique (ci-dessus int
de largeur de bit), cette égalité sera pour tout type entier non signé de 32 bits ou plus, y compris 64 bits et 128 bits.
Remarque: Comment un compilateur énumère tous les 64 bits de motifs dans un délai raisonnable? Il ne peut pas. Les boucles ont été optimisés. Sinon nous serions tous morts avant l'exécution terminée.
Au départ, j'ai seulement joué pendant 16-bits entiers non signés; malheureusement, le C++ est un fou de la langue où les petits entiers (petites bitwidths qu' int
) sont d'abord converties en int
.
#include <iostream>
int main() {
unsigned const MAX = 65536;
for (unsigned i = 0; i < MAX; ++i) {
for (unsigned j = 0; j < MAX; ++j) {
std::uint16_t const a = static_cast<std::uint16_t>(i);
std::uint16_t const b = static_cast<std::uint16_t>(j);
auto const champion = (a + (b & 255)) & 255;
auto const challenger = (a + b) & 255;
if (champion == challenger) { continue; }
std::cout << "a: " << a << ", b: " << b << ", champion: "
<< champion << ", challenger: " << challenger << "\n";
return 1;
}
}
std::cout << "Equality holds\n";
return 0;
}
Et encore une fois, selon Clang: l'Égalité détient.
Eh bien, là vous allez :)
1bien sûr, si un programme de jamais, par inadvertance, déclenche un Comportement Indéfini, il ne serait pas s'avérer beaucoup.