2010-09-28 25 views
11

J'ai un problème assez courant dans le code que j'écris au moment où je veux avoir un entier qui ne peut exister qu'à l'intérieur d'une certaine plage où la plage est [start, end). Fondamentalement, je veux être en mesure de faire quelque chose comme ce qui suit:Existe-t-il une classe Cyclic Integer standard en C++?

cyclic_int ci(4, 8); 

ci = 4; 
assert(ci == 4); 
ci += 3; 
assert(ci == 7); 
ci += 2; 
assert(ci == 5); 
assert(ci == 13); 

Et cela devrait retourner vrai. Fondamentalement, la classe applique automatiquement le module (%) pour moi et l'entier agit comme un entier cyclique dans la plage avec laquelle je l'initie. Je pourrais implémenter moi-même cette classe et surcharger tous les opérateurs communs pour qu'elle fonctionne bien avec des nombres entiers normaux mais cela semble être une classe utile que quelqu'un aurait pu faire auparavant. Donc, ma question est la suivante, y at-il un cours commun comme celui-ci quelque part que tout le monde utilise ou est-ce que je pense à le faire dans le mauvais sens et y a-t-il un moyen plus simple. (Mon but est de ne pas avoir à penser constamment à appliquer l'opérateur% ou une fonction similaire par-dessus) Merci.

Edit: j'ai décidé d'écrire mon propre un aussi juste pour le plaisir: http://github.com/robertmassaioli/wrapping_number

+1

En ce qui concerne Comme je sais, il n'y a pas de «norme de l'industrie» pour ce genre de chose - comme une bibliothèque Boost, si c'est ce que vous voulez dire. Mais comme vous l'avez dit, il devrait être assez facile de mettre en œuvre une telle classe et de surcharger tous les opérateurs nécessaires. –

+1

Utiliser un commentaire au lieu d'une réponse car 1) Je ne l'ai jamais utilisé et 2) Ce n'est pas encore une bibliothèque Boost officielle mais: Boost.ConstrainedValue a un "wrapping_int" qui ressemble beaucoup à ce que vous recherchez: http: //Estudent.agh.edu.pl/~kawulak/constrained_value/constrained_value/tutorial.html#constrained_value.tutorial.other_error_policies_for_bounded_objects –

+0

@Eric: C'est exactement ce que je cherchais mais il n'est pas encore à part des bibliothèques boost. J'ai essayé de regarder autour et je n'ai pas pu trouver une implémentation de référence. Je vais continuer à chercher mais savez-vous où l'on est? –

Répondre

2

Je ne l'ai jamais utilisé et ce n'est pas encore une bibliothèque Boost officielle, mais Boost.ConstrainedValue a un wrapping_int qui ressemble beaucoup à ce que vous cherchez.

Bien qu'il ne soit pas encore partie de Boost, il a été examiné et, IIUC, conditionnellement accepté récemment: http://lists.boost.org/boost-announce/2010/09/0265.php

La bibliothèque est disponible à http://rk.dl.pl/f/constrained_value.zip

La documentation est à http://rk.dl.pl/r/constrained_value

+0

J'ai aussi écrit le mien juste pour m'amuser aussi: http://github.com/robertmassaioli/wrapping_number –

4

est-il pas plus facile d'utiliser la fonction normalize?

int normalize(int val, int start, int end) 
{ 
    return (val - start) % (end - start) + start; 
} 


int ci = 4; 
assert(ci == 4); 
ci = normalize(ci + 3, 4, 8); 
assert(ci == 7); 
ci = normalize(ci + 2, 4, 8); 
assert(ci == 5); 
assert(ci == 13); 
+1

C'était exactement ce que j'essayais d'éviter parce que je ne veux pas vraiment penser à appliquer la fonction de normalisation (parce que j'oublierai éventuellement). Et la dernière affirmation échouera aussi je pense? –

+0

En fait, je pense que la dernière affirmation devrait échouer, parce que 13 n'est pas défini comme étant un nombre limité par la gamme, j'utiliserais assert (ci == cyclic_int <4,8> (13)); (modèle est pratique ici) – stefaanv

+0

@stefaanv: Je pense que ce qu'il obtient est que 13 devrait être congruent à 5 dans le cyclic_int (4, 8) (c'est-à-dire comprend les entiers 4, 5, ...12), ce qui est. Je suis d'accord avec la notion de modèle ... fournit un typage plus fort. – andand

1

Ceux-ci ne peuvent être exactement ce que vous voulez, mais vous pouvez être intéressé par l'une des nombreuses bibliothèques de Galois là-bas (http://www.google.co.uk/search?q=galois+field+c%2B%2B+library). Je n'ai jamais utilisé aucun d'eux, donc je ne peux pas donner une recommandation spécifique.