|
#1 - 10-11-2010 09:18:24
- scarta
- Elite de Prise2Tete
- Enigmes résolues : 49
- Messages : 1968
Arithmétiqe et informatique
Les codeurs fous n'auront aucun mal avec ces petits problèmes, pour les autres c'est une bonne occasion de découvrir les subtilités de l'informatique.
Dans un ordinateur, les nombres entiers sont représentés via des bits, qui correspondent à l'écriture de ces nombres en base 2. Par exemple, 37 s'écrit 100101 en binaire Par ailleurs, un processeur propose un jeu d'instructions, plus ou moins coûteuses en temps. Par exemple, "Comparer deux nombres" ou "Faire une division de deux nombres".
Parmi les opérations les moins coûteuses, on trouve - les opérateurs logiques * ET, qui agit sur 2 bits et donne comme résultat 1 si et seulement si les deux bits valent 1, * OU, qui agit sur 2 bits et donne comme résultat 1 si et seulement si l'un des deux bits au moins vaut 1, * XOR ou OU EXCLUSIF, qui agit sur 2 bits et donne comme résultat 1 si et seulement si un et un seul des deux bits vaut 1 - les décalages * DÉCALAGE DROITE décale tous les bits d'un nombre d'un certain nombre de crans vers la droite * DÉCALAGE GAUCHE décale tous les bits d'un nombre d'un certain nombre de crans vers la gauche - certains indicateurs de tests * Savoir si le dernier résultat vaut 0
Parmi les opérations un peu plus coûteuses, on trouve - les opérateurs arithmétiques + et -
Parmi les opérations encore plus coûteuses, on trouve - les opérateurs arithmétiques * et /, ainsi que le modulo
Sachant tout cela, quel est le moyen le plus rapide de répondre à ces questions, en utilisant uniquement les opérations ci-dessus et de préférence les moins coûteuses?
1.1) Comment multiplier un nombre par 2 ? 1.2) Comment multiplier un nombre par 2^n ?
2.1) Comment diviser un nombre par 2 ? 2.2) Comment diviser un nombre par 2^n ?
3) Comment savoir si deux nombres sont identiques ?
4.1) Comment calculer le modulo 2 d'un nombre ? 4.2) Comment calculer le modulo 2^n d'un nombre ?
5) Comment savoir si un nombre est une puissance de 2 ?
6) Comment savoir si la somme de deux nombres vaut 1 de moins qu'une puissance de 2?
#2 - 10-11-2010 10:03:31
- Barbabulle
- Professionnel de Prise2Tete
- Enigmes résolues : 49
- Messages : 237
Aritthmétique et informatique
1.1) Comment multiplier un nombre par 2 ? -> décalage à gauche de 1 (x<<1)
1.2) Comment multiplier un nombre par 2^n ? -> décalage à gauche de n (x<<n)
2.1) Comment diviser un nombre par 2 ? -> décalage à droite de 1 (x>>1), division euclidienne exemples : 34/2=17 => 100010>>1 = 10001, 23/2=11 => 10111>>1=1011
2.2) Comment diviser un nombre par 2^n ? -> décalage à droite de n (x>>n), division euclidienne exemples : 34/8 = 34/2^3 = 100010>>3 = 100=4, 70/16 = 70/2^4 = 1000110<<4 = 100 = 4
3) Comment savoir si deux nombres sont identiques ? -> on XOR les deux nombres et on vérifie que le résultat est égal à 0, (x^y==0) exemples : 13==13 ? 1101^1101 = 0 : ok, 19==21 ? 10011^10101 = 110 : nok
4.1) Comment calculer le modulo 2 d'un nombre ? -> on ne garde que le le bit de poid faible en faisant ET 1 (x&1) exemples : 65 modulo 2 = 1000001 & 1 = 1, 34 modulo 2 = 100010 & 1 = 0
4.2) Comment calculer le modulo 2^n d'un nombre ? -> on ne garde que les n bits de poids faible an faisant ET n (x&(n-1)) exemples : 72 modulo 16 = 72 modulo 2^4 = 72 & 15 = 1001000 & 1111 = 1000 = 8
5) Comment savoir si un nombre est une puissance de 2 ? -> on test x&(x-1), si c'est égal à 0, c'est une puissance de 2 exemples = 72 => 72&71 = 1001000 & 1000111 =1000000 => non, 64 => 64 & 63 = 1000000 & 111111 = 0 => ok
6) Comment savoir si la somme de deux nombres vaut 1 de moins qu'une puissance de 2? -> on test x&y, si c'est égal à 0, c'est bon. exemple : 25 + 15 = 40 => 11001 & 1111 = 1001 => non, 25 + 6 = 31 => 11001 & 110 = 0 => ok.
Edit : une erreur s'est glissée dans le 4.2 : il faut lire x&((2^n)-1) au lieu de x&(n-1) Edit 2 : suite à la mise au point de scarta, il faut en fait lire x&((1<<n)-1)
La paix dans le monde n'est pas menacée par les révoltés, mais par les soumis. Georges Bernanos
#3 - 10-11-2010 11:49:23
- racine
- Elite de Prise2Tete
- Enigmes résolues : 49
- Messages : 1224
aritgmétique et informatique
Pour ma culture, quand tu parles de coût en temps c'est chiffrable directement en temps? Il y a des ratios constants? Du genre multiplier 2 et 3 prend 2 fois plus de temps qu'additionner 2 et 3.
Merci pour ta réponse.
#4 - 10-11-2010 12:53:13
- dhrm77
- L'exilé
- Enigmes résolues : 49
- Messages : 3004
- Lieu: Fanning Island-?-Lac Tele,Mali
arithmétiqur et informatique
Bon, c;est simple pour moi...
1.1) Comment multiplier un nombre par 2 ? on decale a gauche 1 fois 1.2) Comment multiplier un nombre par 2^n ? on decale a gauche n fois
2.1) Comment diviser un nombre par 2 ? on decale a droite 1 fois 2.2) Comment diviser un nombre par 2^n ? on decale a droite n fois
3) Comment savoir si deux nombres sont identiques ? on teste si a xor b = 0
4.1) Comment calculer le modulo 2 d'un nombre ? on fait un ET avec 1
4.2) Comment calculer le modulo 2^n d'un nombre ? on fait un ET avec 2^n-1 ou en detail, soit le nombre X: - on prend A=0 - on decale A a gauche et ajoute 1, n fois - on fait un X & A
5) Comment savoir si un nombre est une puissance de 2 ? on decale a droite tant que n & 1 = 0 si le resultat est 1, c'est une puissance de 2.
6) Comment savoir si la somme de deux nombres vaut 1 de moins qu'une puissance de 2? il y a peut etre un piege, mais... - on additionne les 2 nombres. - on decale a droite tant que n & 1 = 1 - on teste que le resultat est 0.
Great minds discuss ideas; Average minds discuss events; Small minds discuss people. -Eleanor Roosevelt
#5 - 10-11-2010 14:21:14
- scarta
- Elite de Prise2Tete
- Enigmes résolues : 49
- Messages : 1968
Arithmétiqque et informatique
Petite précision générale: pour le 4.2, l'entrée est N et pas 2^N
@racine: il n'y a pas vraiment de ratio théorique constant, ça dépend beaucoup de l'architecture du processeur, et beaucoup ont développé des moyens astucieux pour faire des multiplications plus rapidement (avec parfois quelques erreurs, par exemple: http://fr.wikipedia.org/wiki/Bug_de_la_ … du_Pentium ou comment une méthode pour faire des divisions plus rapidement fout en l'air toute une gamme de processeur)
@dhrm77: tes réponses ne sont pas fausses, loin de là; à ceci près que les mécanismes de type "boucle" ne sont pas dans le jeu d'instructions que j'ai défini dans l'énoncé (du coup, il faut faire tenir chaque réponse en une seule instruction "haut niveau")
#6 - 10-11-2010 16:28:28
- shadock
- Elite de Prise2Tete
- Enigmes résolues : 39
- Messages : 3334
Arithméétique et informatique
Message vide pour le moment.
"L'expérience est une lanterne qui n'éclaire que celui qui la porte." L-F. Céline
#7 - 10-11-2010 17:30:47
- luthin
- Professionnel de Prise2Tete
- Enigmes résolues : 36
- Messages : 124
arirhmétique et informatique
Il m'arrive effectivement de coder, mais j'avoue ne jamais avoir poussé l'optimisation d'un code à ce point. J'y penserai sans doute la prochaine fois. Cependant, je ne connaissais pas certaines fonctions comme les décalages...
1.1) 2*p=p+p. On remplace donc la multiplication par une addition. 1.2) p*2^n. Ca revient à décaler tous les bits de p de n crans vers la gauche.
2.1) p/2=p*2^(-1). On décale tous les bits de p de 1 cran vers la droite. Si la variable à laquelle on assigne le résultat est déclarée comme un entier, le résultat est E(p/2). 2.2) p/2^n=p*2^(-n). On décale tous les bits de p de n crans vers la droite. Même remarque qu'en 2.1).
3) p==q <=> p-q==0. On fait donc la soustraction et on regarde si tous les bits du résultat sont nuls (ca revient à faire une boucle sur tous les bits de var=p-q). Enfin, je pense qu'il existe toujours dans les langages de programmation des indicateurs de test "==", je suppose qu'ils en tiennent déjà compte, non?
4.1) p mod(2)=1 si p est impair <=> si le premier bit de p est 1 (en partant de la droite) p mod(2)=0 si p est pair <=> si le premier bit de p est 0. Le résultat est donc la valeur du premier bit de p (en partant de la droite). 4.2) p mod(2^n). On remplace tous les bits qui ont un poids >=2^n par 0.
5) p==2^n <=> Un seul bit de p vaut 1. Ca revient encore à faire une boucle sur tous les bits de p...
6) p+q==2^n-1 <=> tous les bits de p+q valent 1. idem...
Bon, j'ai souvent fait intervenir des boucles, mais tu n'en parles pas, il me manque sûrement quelque chose... Intéressant, merci.
#8 - 10-11-2010 17:41:52
- MthS-MlndN
- Hors d'u-Sage
- Enigmes résolues : 49
- Messages : 12,414E+3
- Lieu: Rouen
Arithmétique et infoormatique
Très bonne idée, cette énigme/rappels
Pour les 1 et 2, il s'agit de décalages : 1.1) décaler d'un cran sur la gauche 1.2) décaler de n crans sur la gauche 2.1) décaler d'un cran sur la droite 2.2) décaler de n crans sur la droite
Pour le 3, une comparaison bit à bit suffit : si (bit 1 du nombre 1 XOR bit 1 du nombre 2) OU (bit 2 du nombre 1 XOR bit 2 du nombre 2) OU ... vaut 1, alors les nombres sont différents (on peut arrêter la vérification au premier XOR qui vaut 1, si ça arrive).
4.1) C'est son dernier bit. 4.2) C'est le nombre constitué de ses n derniers bits. Comment le faire seulement avec les opérations que tu donnes au début ? Je ne vois pas pour l'instant.
5) Si un seul bit du nombre vaut 1, alors ce nombre est une puissance de 2. Autrement dit, on veut (bit 1) XOR (bit 2) XOR (bit 3) XOR ... = 1.
6) Si la somme de deux nombres vaut une puissance de 2 moins 1, cela donnera en binaire 111...111 (avec un nombre quelconque de 1). Donc, si on ne prend pas en compte les 0 qui précèdent, et qu'on considère que les deux nombres sont codés sur le même nombre de bits (i.e. le nombre de bits que prend le plus grand), on veut que (bit du nombre 1) XOR (bit correspondant du nombre 2) vaille 1 à chaque fois, autrement dit : (bit 1 du nb 1 XOR bit 1 du nb 2) AND ... AND (bit n du nb 1 XOR bit n du nb 2) = 1 Le cas échéant, on peut s'arrêter dès qu'un des termes vaut 0 (comme pour le 3).
Podcasts Modern Zeuhl : http://radio-r2r.fr/?p=298
#9 - 10-11-2010 22:17:35
- rivas
- Elite de Prise2Tete
- Enigmes résolues : 48
- Messages : 1106
- Lieu: Jacou
Arithmétique et informtique
Merci de faire découvrir cela aux non informaticiens. C'est une très bonne idée. On pourrait sans doute aller un peu plus loin dans une suite...
Tu as oublié à mon avis quelques opérateurs très importants: NOT qui inverse tous les bits d'un nombre, INC qui augmente de 1 (plus rapide qu'une addition générale) et DEC qui diminue de 1.
1.1: Décalage à gauche de 1 bit (A << 1) 1.2: Décalage à gauche de n bits (A << n)
2.1: Décalage à droite de 1 bit 2.2: Décalage à droite de n bits
3: A-B et on teste le bit permettant de savoir si le résultat est 0 On peut aussi faire NOT (A XOR (NOT B)) et vérifier si le résultat est 0
4.1: A ET 1: on isole le bit de poids faible) 4.2: A ET ((1 << n)-1): on isole les n bits de poids faible.
5: A ET (A-1) et on teste le bit de résultat nul. Si A est une puissance de 2, 2^n, A s'écrit avec un 1 suivi de n zéros, A-1 s'écrit avec n chiffres 1. Le ET donne donc 0. Si A n'est pas une puissance de 2, A-1 et A ont le même bit de poids fort et donc le ET ne donne pas 0
6: Si A+B donne une puissance de 2 moins -1, c'est qu'il ne s'écrit qu'avec des 1. Regardons le bit de poids faible. Pour valoir 1, il faut qu'il soit à 1 dans un des nombres et à 0 dans l'autre et ne génère pas de retenue. La situation du bit 1 est la même et ainsi de suite. Donc bit à bit, il y a à chaque fois 1 1 et 1 0. Donc XOR entre A et B donnera que des 1 et donc (A XOR B) ET ((A XOR B)+1) sera nul. (on ne calcule A XOR B qu'une fois). I doit y avoir mieux, je vais creuser...
Pour ceux qui aiment ça: http://graphics.stanford.edu/~seander/b … With64Bits
#10 - 11-11-2010 10:20:58
- Yannek
- Passionné de Prise2Tete
- Enigmes résolues : 10
- Messages : 60
arithmétique rt informatique
On suppose que l'on travaille avec des entiers non signés.
1. Multiplication par 2 ou 2^n 1a. 2*N = G(1) N (un décalage à gauche) 1b. 2^n*N = G(n) N (n décalages à gauche)
2. Quotient de la division euclidienne par 2 ou 2^n 2a. N div 2 = D(1) N (un décalage à droite) 2b. N div 2^n=D(n) (n décalages à droite)
3. Test d'égalité N=M ssi N xor M=0
4. Reste de la division euclidienne par 2 ou 2^n 4.a. N mod 2 = N xor (G(1)D(1) N) 4.b. N mod 2^n = N xor (G(n)D(n) N)
5. Tester si N est une puissance de 2 N et (N-1)=0
6. Tester si N+M+1 est une puissance de 2 (N ou M) xor (N xor M)=0
Je me suis peut-être trompé pour les deux derniers, j'y réfléchis.
#11 - 11-11-2010 11:23:44
- Palin01
- Passionné de Prise2Tete
- Enigmes résolues : 39
- Messages : 70
- Lieu: Lille
arirhmétique et informatique
1-1) En base n, si on multiplie un nombre par n on "rajoute un 0 à droite" donc ici on fait l'opération "Décaler à gauche d'un cran" 1-2)soit N = [latex] a_m 2^m+a_{m-1} 2^{m-1} +...+a_0 2^0[/latex] [latex]N* 2^n=a_m 2^{m+n}+a_{m-1}2^{m-1+n}+...+a_02^n[/latex]et ensuite tous les coefficients des puissances de 2 inférieurs à n sont nuls : on "rajoute" donc n zéros. On fait donc l'opération "Décaler à gauche de n crans"
2) En informatique la division prend 2 entiers et renvoie un entier : par exemple 9/2=4. 2-1)De la même manière qu'au 1-1) on fait "Décaler à droite d'un cran" 2-1)"Décaler à droite de n crans "
Je continuerai plus tard si j'ai le temps. Plutôt amusant sinon . --------------- Bon ben j'ai plus de trop de temps là donc j'essaye le 3) rapidement : on fait un XOR sur le premier bit de chaque nombre,c'est à dire le plus à droite, (ça doit être permis sinon je vois pas comment faire), puis on test si le dernier résultat est 0 : Si oui alors on décale à droite et on continue sinon on arrête et on renvoie faux.
#12 - 11-11-2010 22:28:12
- shadock
- Elite de Prise2Tete
- Enigmes résolues : 39
- Messages : 3334
Aithmétique et informatique
"L'expérience est une lanterne qui n'éclaire que celui qui la porte." L-F. Céline
#13 - 11-11-2010 23:05:53
- scarta
- Elite de Prise2Tete
- Enigmes résolues : 49
- Messages : 1968
Arithmétique et inforatique
Des bonnes réponses un peu partout mais aucun "carton plein". Notations : & signifie ET, ^ signifie XOR, | signifie OU, <<n signifie "Décalage gauche de n crans", >>n signifie "Décalage droite de n crans"
Voici donc les réponses: 1.1) Multiplier par 2 en base 2, c'est comme multiplier par 10 en base 10: on ajoute un 0. Autrement dit, on fait x <<1 1.2) Pareil, on ajoute n zéros: x <<n
2.1) Dans la même logique, on divise par 2 en binaire en ôtant le dernier chiffre (il s'agit de division euclidienne, sans reste). Autrement dit, on fait x >>1 2.2) Pareil, on ôte n chiffres: x >>n
3) 0^0 = 0, 1^1 = 0, et 0^1 = 1. Autrement dit, si x=y, alors x^y=0. Donc on fait x^y et on regarde l'indicateur de résultat nul
4.1) Le modulo 2 d'un nombre en binaire, c'est comme le modulo 10 d'un nombre en base 10: le dernier chiffre. De plus, x&0 = 0 et x&1 = x. Autrement dit, x&1 nous donne le modulo 2 de x
4.2) Celle-ci n'était pas évidente: * la réponse la plus communément admise est de faire x & ((1<<n)-1). En effet, 1<<n, c'est 1 avec n zéros derrière, donc (1<<n)-1, c'est n fois le chiffres 1 et x&((1<<n)-1), c'est donc les n derniers chiffres de x (qui, comme en base 10 pour 10^n, correspondent au modulo en base 2 de 2^n) * cependant, pour faire des opérations moins coûteuses, on peut procéder autrement: en effet, x^0 = x et x^x = 0; et de plus (x>>n)<<n correspond à x auquel on remplace les n derniers nombres par des zéros (pour s'en convaincre, en base 10, si je prends le quotient de x divisé par 10^n, puis que je rajoute n zéros, j'obtient un nombre similaire à x sauf que ses n derniers chiffres sont nuls). Du coup, x^((x>>n)<<n) vaut - le i-ème bit de x pour les n derniers bits - 0 pour ceux qui sont devant
5) Sans faire de boucle, le plus simple est de faire x & (x-1) et de regarder l'indicateur de résultat nul. En effet, si x est une puissance de 2, c'est un 1 avec n zéros derrière, et x-1 c'est n fois le chiffre 1. L'un ET l'autre, ça donne donc zéro. 2 remarques pour celle-ci: - Elle indique que 0 est une puissance 2 (mais comme je ne parle pas des nombres négatifs dans l'énoncé, on peut oublier cette limitation) - Elle fait une opération "-". Faire une boucle pour vérifier qu'on n'a que des zéros, suivi d'un 1 et plus rien ensuite ne fait pas de -, mais d'un autre côté la boucle peut être plus longue (car pour 2^n, on bouclera n+1 fois). De toutes les façons, les boucles ne font pas partie des opérations prévues par l'énoncé.
6) Je pense que le plus simple est de faire (a^b)&(a^b +1) et de regarder l'indicateur de résultat nul J'ai beaucoup réfléchi au "(N ou M) xor (N xor M)=0" de Yanneck, je comprenais pas pourquoi ça marchait et en fait ça marche pas si deux bits valent 0, la condition reste vraie alors qu'elle devrait être fausse
Edit: Pour ce point 6, il y a en fait plus simple en utilisant une fonction binaire que je n'ai pas présenté dans l'énoncé: le NOR (qui vaut 1 si et seulement si les deux opérandes sont nulles) Du coup, le test de résultat nul après (a NOR b) XOR (a AND b) devrait faire l'affaire:
#14 - 12-11-2010 12:22:56
- Nicouj
- Professionnel de Prise2Tete
- Enigmes résolues : 27
- Messages : 330
arithmétuque et informatique
7) Comment inverser les valeurs de deux registres R1 et R2 quand aucun autre est disponible ?
#15 - 12-11-2010 16:43:15
- rivas
- Elite de Prise2Tete
- Enigmes résolues : 48
- Messages : 1106
- Lieu: Jacou
arithméyique et informatique
Déjà posé Spoiler : [Afficher le message] R1=R1+R2 R2=R2-R1 R1=R1-R2
#16 - 12-11-2010 17:23:13
- Nicouj
- Professionnel de Prise2Tete
- Enigmes résolues : 27
- Messages : 330
arithmérique et informatique
Héhé on peut faire bien mieux
#17 - 12-11-2010 17:44:52
- rivas
- Elite de Prise2Tete
- Enigmes résolues : 48
- Messages : 1106
- Lieu: Jacou
Arithmétiqu et informatique
On peut faire pareil avec XOR. Est-ce à ça que tu penses? Il y a le même nombre d'instructions et sur les processeurs récents ça doit être équivalent. Spoiler : [Afficher le message] R1=R1 XOR R2 R2=R2 XOR R1 R1=R1 XOR R2
Sur les processeurs ARM on doit pouvoir faire mieux en utilisant les instructions spéciales du "barrel shifter" mais c'est un peu spécifique. Sur les processeurs graphiques aussi. Sur les Intel on doit pouvoir charger 2 32bits dans un 64 et faire un swap mais la aussi ce n'est pas générique...
#18 - 12-11-2010 19:52:53
- Nicouj
- Professionnel de Prise2Tete
- Enigmes résolues : 27
- Messages : 330
Arithmétiue et informatique
oui tout fait. Le XOR a l'avantage par rapport à l'addition/soustraction de ne pas avoir de propagation de retenue et se font donc plus vite
#19 - 13-11-2010 01:31:10
- dhrm77
- L'exilé
- Enigmes résolues : 49
- Messages : 3004
- Lieu: Fanning Island-?-Lac Tele,Mali
arithmétique et infprmatique
scarta a écrit:6) Comment savoir si la somme de deux nombres vaut 1 de moins qu'une puissance de 2?
Pourquoi ne pas faire comme dans 5), mais inversé: soit les 2 nombres a et b: faire x=a+b faire ensuite (x & (x+1))==0
Great minds discuss ideas; Average minds discuss events; Small minds discuss people. -Eleanor Roosevelt
#20 - 13-11-2010 22:00:39
- scarta
- Elite de Prise2Tete
- Enigmes résolues : 49
- Messages : 1968
Arithmétique et informtaique
Ce que tu proposes fait 2 opérations arithmétiques et une logique, tandis que l'autre solution fait 2 opérations logiques et une arithmétiques, donc ça fait toujours un peu moins (d'après l'énoncé hein, je sais bien que les processeurs actuels sont capables de faire des additions en 1 temps d'horloge) Ceci dit (a NOR b) XOR (a AND b) ==0 fait encore moins (3 opérations logiques)
Mots clés des moteurs de recherche
|
|