Je pense en particulier à la manière d'afficher les contrôles de pagination, lorsqu'on utilise un langage tel que C# ou Java.
Si j'ai x que je veux afficher dans des morceaux de y par page, combien de pages seront nécessaires ?
Je pense en particulier à la manière d'afficher les contrôles de pagination, lorsqu'on utilise un langage tel que C# ou Java.
Si j'ai x que je veux afficher dans des morceaux de y par page, combien de pages seront nécessaires ?
Convertir en virgule flottante et inversement semble être une énorme perte de temps au niveau du CPU.
La solution de Ian Nelson :
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;
On peut le simplifier :
int pageCount = (records - 1) / recordsPerPage + 1;
D'après les informations disponibles, cette méthode ne présente pas le bogue de dépassement de capacité signalé par Brandon DuRette et, comme elle ne l'utilise qu'une seule fois, il n'est pas nécessaire de stocker le paramètre recordsPerPage, surtout s'il provient d'une fonction coûteuse permettant de récupérer la valeur d'un fichier de configuration ou autre.
Cela pourrait être inefficace, si config.fetch_value utilisait une consultation de base de données ou autre :
int pageCount = (records + config.fetch_value('records per page') - 1) / config.fetch_value('records per page');
Cela crée une variable dont vous n'avez pas vraiment besoin, ce qui a probablement des implications (mineures) en termes de mémoire et représente tout simplement trop de travail de saisie :
int recordsPerPage = config.fetch_value('records per page')
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;
Il s'agit d'une seule ligne, qui ne récupère les données qu'une seule fois :
int pageCount = (records - 1) / config.fetch_value('records per page') + 1;
+1, le problème des enregistrements nuls qui renvoient toujours 1 pageCount est en fait pratique, puisque je voudrais toujours avoir 1 page, montrant le placeholder/fausse ligne de "aucun enregistrement ne correspond à vos critères", permet d'éviter tout problème de "0 page count" dans le contrôle de pagination que vous utilisez.
Sachez que les deux solutions ne renvoient pas le même pageCount pour les enregistrements nuls. Cette version simplifiée renvoie 1 pageCount pour des enregistrements nuls, alors que la version de Roland Backhouse renvoie 0 pageCount. C'est bien si c'est ce que vous désirez, mais les deux équations ne sont pas équivalentes lorsqu'elles sont exécutées par la division d'entiers à la C#/Java.
Petite modification pour la clarté pour les personnes qui le scannent et qui manquent les bodmas en passant de la solution Nelson à la simplification (comme je l'ai fait la première fois !), la simplification avec les parenthèses est... int pageCount = ((records - 1) / recordsPerPage) + 1 ;
Vous devez également convertir la sortie en int
parce que Math.Ceiling
renvoie un double
o decimal
en fonction des types d'entrée.
Cela devrait vous donner ce que vous voulez. Le problème, c'est lorsque les nombres sont inégaux. Ainsi, s'il y a une page partielle, il faut aussi ajouter une page.
int x = number_of_items;
int y = items_per_page;
// with out library
int pages = x/y + (x % y > 0 ? 1 : 0)
// with library
int pages = (int)Math.Ceiling((double)x / (double)y);
X/y + ! !(x % y) évite la branche pour les langages de type C. Il y a cependant de fortes chances que votre compilateur le fasse de toute façon.
+1 pour ne pas déborder comme les réponses ci-dessus... bien que convertir des ints en doubles juste pour Math.ceiling et ensuite de nouveau est une mauvaise idée dans un code sensible aux performances.
La solution de calcul des nombres entiers fournie par Ian est intéressante, mais elle souffre d'un bogue de dépassement des nombres entiers. En supposant que les variables sont toutes int
la solution pourrait être réécrite pour utiliser long
les mathématiques et éviter le bug :
int pageCount = (-1L + records + recordsPerPage) / recordsPerPage;
Si records
est un long
mais le problème demeure. La solution du module ne présente pas le bogue.
Je ne pense pas qu'il soit réaliste de penser que vous allez rencontrer ce bug dans le scénario présenté. 2^31 enregistrements, c'est beaucoup de choses à parcourir.
@finnw : AFAICS, il n'y a pas d'exemple réel sur cette page, juste un rapport de quelqu'un qui a trouvé le bug dans un scénario théorique.
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.
1 votes
J'ai raté quelque chose ? y/x + 1 fonctionne très bien (à condition que vous sachiez que l'opérateur / arrondit toujours vers le bas).
64 votes
@rikkit - si y et x sont égaux, y/x + 1 est un de trop.
1 votes
Pour ceux qui viennent de découvrir ça, cette réponse à une question de dupe évite la conversion inutile en double y évite les problèmes de débordement en plus de fournir une explication claire.
3 votes
@IanNelson plus généralement si
x
est divisible pary
,y/x + 1
serait un de trop.1 votes
@ZX9 Non, cela ne permet pas d'éviter les problèmes de débordement. C'est exactement la même solution que celle que Ian Nelson a postée ici.