2010-08-19 19 views
21

Quand les gens parlent de l'utilisation des «nombres magiques» dans la programmation informatique, que veulent-ils dire?Que sont les "nombres magiques" dans la programmation informatique?

+15

Un chiffre magique est 42 :) –

+0

Non, il n'y a rien de magique 42. 42 en fait _is_ 6 de 9 (si vous utilisez la base 13). DeepThought et la Terre avaient raison! – paxdiablo

+4

@Victor: Cela devrait être 'THE_ANSWER_TO_THE_UNIVERSE_THE_WORLD_AND_EVERYTHING = 42' – mpen

Répondre

37

Les nombres magiques sont des nombres dans votre code qui ne sont pas immédiatement évidents pour quelqu'un avec très peu de connaissances.

Par exemple, la pièce de code suivante:

sz = sz + 729; 

a un nombre magique et serait bien mieux écrire:

sz = sz + CAPACITY_INCREMENT; 

Certains état extrême de vues que vous ne devriez jamais avoir tous les chiffres dans votre code sauf -1, 0 et 1 mais je préfère une vue un peu moins dogmatique puisque je reconnaîtrais instantanément 24, 1440, 86400, 3.1415, 2.71828 et 1.414 - tout dépend de vos connaissances.

Cependant, même si je sais il y a 1440 minutes dans une journée, je ne serais probablement encore utilise un identifiant MINS_PER_DAY car il rend leur recherche beaucoup plus facile. A qui de dire que l'augmentation de capacité mentionnée ci-dessus ne serait pas 1440 et que vous finissez par changer la mauvaise valeur? Ceci est particulièrement vrai pour les faibles nombres: la probabilité d'utilisation double de 37197 est relativement faible, la chance d'utiliser 5 pour plusieurs choses est assez élevée.

L'utilisation d'un identifiant signifie que vous n'avez pas besoin de parcourir tous vos 700 fichiers source et de changer 729 en 730 lorsque l'incrément de capacité a changé. Vous pouvez simplement changer une ligne:

#define CAPACITY_INCREMENT 729 

à:

#define CAPACITY_INCREMENT 730 

et recompiler le lot.


contraste avec les constantes magiques qui sont le résultat des gens naïfs qui pensent que juste parce qu'ils retirent les chiffres réels de leur code, ils peuvent changer:

x = x + 4; 

à:

#define FOUR 4 
x = x + FOUR; 

Cela ajoute absolument zéro informations supplémentaires à votre code et est une perte de temps totale.

+3

+1 pour un bon exemple de comment ne pas le faire (thedailywtf avait une grande collection de ceux hier seulement: http://thedailywtf.com/Articles/Avoiding-Magic-Constants.aspx) – delnan

+0

Oui, j'ai lu celui-là moi-même. J'ai particulièrement aimé le '#define STR1" 1 "', '#define STR9" 1 "' à la fin (paraphrasant). – paxdiablo

+0

Les nombres magiques plutôt que les constantes nommées sont susceptibles de se casser lorsqu'ils sont modifiés. Si le même numéro est utilisé à plusieurs fins, il est susceptible d'être modifié à toutes fins et/ou seulement dans certains cas. Les constantes nommées réduisent significativement cette casse. – BillThor

5

« nombres magiques » sont des nombres qui apparaissent dans des déclarations comme

if days == 365 

En supposant que vous ne saviez pas qu'il y avait 365 jours par an, vous pouvez trouver cette déclaration dénuée de sens. Ainsi, il est une bonne pratique d'attribuer tous les « magiques » numéros (numéros qui ont une sorte d'importance dans votre programme) à une constante,

DAYS_IN_A_YEAR = 365 

Et à partir de là, à comparer qu'au lieu. C'est plus facile à lire, et si la Terre est désaxée et que nous gagnons un jour de plus ... vous pouvez facilement le changer (d'autres nombres pourraient être plus susceptibles de changer).

+1

"si la terre est désaxée, et nous gagnons un jour de plus" - Bizarre, cela semble se produire tous les quatre ans. :) –

+1

Le morceau de code le plus drôle que j'ai jamais vu: '#define PI 3.14159/* make define au cas où PI changerait jamais * /' :-) – paxdiablo

+0

La terre est désaxée tous les quatre ans ?! Hou la la! – Nick

1

Le terme nombre magique est généralement utilisé pour décrire une constante numérique dans le code. Le nombre apparaît sans autre description et sa signification est donc ésotérique.

L'utilisation de nombres magiques peut être évitée en utilisant des constantes nommées.

2

Tout ce qui n'a pas de signification apparente à qui que ce soit, sauf l'application elle-même.

if (foo == 3) { 
    // do something 
} else if (foo == 4) { 
    // delete all users 
} 
0

Utilisation des numéros dans les calculs autres que 0 ou 1 qui ne sont pas définis par un identifiant ou variable (ce qui rend non seulement le nombre facile à changer en plusieurs endroits en le changeant en un seul endroit, mais fait aussi clair pour le lecteur à quoi sert le nombre).

2

Les nombres magiques sont des valeurs spéciales de certaines variables qui font que le programme se comporte d'une manière spéciale. Par exemple, une bibliothèque de communication peut prendre un paramètre Timeout et définir le nombre magique "-1" pour indiquer un délai d'attente infini.

4

Wikipedia est votre ami (Magic Number article)

+4

+1, pour avoir appris à l'OP à pêcher (j'espère), et pas seulement à lui donner le poisson. – Thanatos

+11

Donnez un feu à un homme, il sera chaud pour la nuit. Mettre un homme en feu, il sera chaud pour le reste de sa vie - Terry Pratchett (je pense). Cependant, le SO devrait être capable de se tenir seul - même si le reste de l'Internet disparaît! _ Par tous les moyens lien vers une autre source, mais je préfère mettre un peu de viande dans la réponse aussi bien. – paxdiablo

+1

+1 pour Pratchett! – Paddyslacker

3

La plupart des réponses à ce jour ont décrit un nombre magique comme une constante qui n'est pas auto décrire. Étant moi-même un peu un programmeur "old-school", nous avons décrit les nombres magiques comme étant des constantes qui sont affectées à un but particulier qui influence le comportement du code. Par exemple, le nombre 999999 ou MAX_INT ou quelque chose d'autre complètement arbitraire.

Le gros problème avec les nombres magiques est que leur but peut facilement être oublié, ou la valeur utilisée dans un autre contexte parfaitement raisonnable.

Comme exemple brut et terriblement artificiel:

while (int i != 99999) 
{ 
    DoSomeCleverCalculationBasedOnTheValueOf(i);  

    if (escapeConditionReached) 
    { 
    i = 99999; 
    } 
} 

Le fait que l'on utilise une constante ou non nommée est pas vraiment la question. Dans le cas de mon terrible exemple, la valeur influe sur le comportement, mais que se passe-t-il si nous avons besoin de changer la valeur de "i" en boucle? Clairement dans l'exemple ci-dessus, vous n'avez pas besoin d'un nombre magique pour quitter la boucle. Vous pouvez le remplacer par une déclaration de rupture, et c'est le vrai problème avec les nombres magiques, qu'ils sont une approche paresseuse au codage, et peuvent toujours être remplacés par quelque chose moins enclin à l'échec, ou à perdre du sens au fil du temps.

+0

Je préfère appeler cela une valeur sentinelle moi-même, mais je vois d'où vous venez. – paxdiablo

+1

Pour moi, une valeur sentinelle vit dans une structure de données - généralement une clé qui est trop grande (ou petite) pour être une clé valide. Pour cette terminaison de boucle, cependant, j'ai vu cela (trop souvent) décrit comme étant intrinsèquement préférable à 'break 'parce que" break est un goto caché ". Qu'est-ce que goto réalise? - 'PC = adresse_cible; Pour moi, ces nombres magiques spéciaux ne sont que des versions déguisées et indirectes de la même chose - des affectations qui conduisent l'exécution à un point particulier du code - et sont donc souvent moins lisibles et maintenables que simplement utiliser 'break'. – Steve314

+0

Difficile de croire que le fait de taper 'break' est moins * paresseux que de configurer cette sortie basée sur un nombre magique. – Steve314

4

Il y a plus d'une signification. Celle donnée par la plupart des réponses déjà (un numéro sans nom arbitraire) est très commun, et la seule chose que je vais dire à ce sujet est que certaines personnes vont à l'extrême de la définition ...

#define ZERO 0 
#define ONE 1 

Si vous faites cela, je vais vous traquer et ne montrer aucune pitié.

Un autre type de nombre magique est cependant utilisé dans les formats de fichier. C'est juste une valeur incluse comme typiquement la première chose dans le fichier qui aide à identifier le format de fichier, la version du format de fichier et/ou l'endian-ness du fichier particulier.

Par exemple, vous pourriez avoir un nombre magique de 0x12345678. Si vous voyez ce nombre magique, il est raisonnable de supposer que vous voyez un fichier au format correct. Si vous voyez, en revanche, 0x78563412, il est raisonnable de penser que vous voyez une version échangée en endian du même format de fichier.Le terme "nombre magique" est cependant un peu abusé, se référant à presque tout ce qui identifie un format de fichier - y compris des chaînes ASCII assez longues dans l'en-tête.

http://en.wikipedia.org/wiki/File_format#Magic_number

+1

Je dirais que le deuxième type de nombre magique (c'est-à-dire ceux dans les formats de fichiers) est en fait le type le plus commun/pertinent. – hbw

+0

Cela peut être vrai - après tout, n'importe quel bon programmeur saura mieux que d'utiliser un nombre magique pour spécifier son nombre magique. – Steve314

+1

la "magie" des nombres magiques est leur manque de sémantique inhérente évidente ... soit des identifiants que vous mentionnez ou des facteurs fudge. –

0

En mots simples et vrais, un chiffre magique est un nombre à trois chiffres, dont la somme des carrés des deux premiers chiffres est égale à la troisième. Ex-202, as, 2 * 2 + 0 * 0 = 2 * 2. Maintenant, WAP en Java pour accepter un nombre entier et d'imprimer si un nombre magique ou non.

+2

Certainement pas la description de "nombres magiques d'un point de vue de la programmation". – BoltClock

0

Cela peut sembler un peu banal, mais il y a au moins un vrai nombre magique dans chaque langage de programmation.

Je soutiens que c'est la baguette magique pour les gouverner tous dans pratiquement le carquois de chaque programmeur de baguettes magiques. FAUX est inévitablement 0 VRAI n'est pas (FAUX), mais pas nécessairement 1! Peut être -1 (0xFFFF)

NULL est inévitablement 0 (le pointeur) Et la plupart des compilateurs le permettent à moins que leur typochecking soit complètement enragé.

0 est l'index de base des éléments du tableau, sauf dans les langues qui sont si archaïques que l'index de base est '1'. On peut alors commodément coder pour (i = 0; i < 32; i ++), et s'attendre à ce que 'i' commence à la base (0), et augmente à, et s'arrête à 32-1 ... le 32ème membre de un tableau, ou autre chose.

0 est la fin de nombreuses chaînes de langage de programmation. La valeur "stop here".
0 est également intégré dans les instructions X86 pour «déplacer efficacement les chaînes». Enregistre plusieurs microsecondes.

0 est souvent utilisé par les programmeurs pour indiquer que "rien ne s'est mal passé" dans l'exécution d'une routine. C'est la valeur du code "pas une exception". On peut l'utiliser pour indiquer le manque d'exceptions levées.

Zéro est la réponse la plus souvent donnée par les programmeurs à la quantité de travail qu'il faudrait pour faire quelque chose de complètement trivial, comme changer la couleur de la cellule active en violet au lieu de rose vif. "Zéro, mec, juste comme zéro!"

0 est le nombre de bogues dans un programme que nous aspirons à atteindre. 0 exceptions non comptabilisées, 0 boucles non terminées, 0 voies de récursivité qui ne peuvent pas être réellement prises. 0 est l'asymptote que nous essayons de réaliser en programmant le travail, la «petite amie» (ou le petit ami), les «problèmes», les expériences de restauration moche et les particularités générales de la voiture.

Oui, 0 est un nombre magique en effet. FAR plus de magie que toute autre valeur. Rien ... hum, vient près.

[email protected]