J'ai rencontré un problème théorique intéressant il y a plusieurs années. Je n'ai jamais trouvé de solution et elle continue de me hanter quand je dors.
Supposons que vous ayez une application (C #) contenant un certain nombre dans un entier, appelé x. (La valeur de x n'est pas fixe). Lorsque le programme est exécuté, x est multiplié par 33, puis écrit dans un fichier.
Le code source de base ressemble à ceci:
int x = getSomeInt();
x = x * 33;
file.WriteLine(x); // Writes x to the file in decimal format
Quelques années plus tard, vous découvrez que vous avez besoin des valeurs d'origine de X en arrière. Certains calculs sont simples: divisez simplement le nombre dans le fichier par 33. Cependant, dans d'autres cas, X est suffisamment grand pour que la multiplication provoque un débordement d'entier. Selon les documents , C # tronquera les bits de poids fort jusqu'à ce que le nombre soit inférieur à int.MaxValue
. Est-il possible, dans ce cas, soit:
- Récupérer X lui-même ou
- Récupérer une liste de valeurs possibles pour X?
Il me semble (bien que ma logique puisse certainement être erronée) qu'un ou les deux devraient être possibles, car le cas plus simple de l'addition fonctionne (Essentiellement, si vous ajoutez 10 à X et qu'il se termine, vous pouvez soustraire 10 et finir avec X à nouveau ) et la multiplication est simplement une addition répétée. Il est également utile (je crois) que X soit multiplié par la même valeur dans tous les cas - une constante de 33.
Cela dansait autour de mon crâne à des moments étranges depuis des années. Cela me viendra à l'esprit, je passerai un peu de temps à y réfléchir, puis je l'oublierai pendant quelques mois. J'en ai assez de courir après ce problème! Quelqu'un peut-il offrir un aperçu?
(Note latérale: je ne sais vraiment pas comment marquer celui-ci. Suggestions bienvenues.)
Edit: Permettez-moi de préciser que si je peux obtenir une liste de valeurs possibles pour X, il y a d'autres tests que je pourrais faire pour m'aider à le réduire à la valeur d'origine.
m
n'est que de 2 ^ 32 ou 2 ^ 64, plus l'exponentiation de a
modulo m
est simple (il suffit d'ignorer le débordement là-bas)
r*s^-1 mod m
et vous devez trouver les deux r
et s
. Ici, nous avons r*s mod m
et nous savons tout, mais r
.