tag:blogger.com,1999:blog-91041271201366085442024-02-19T13:36:53.509-08:00J'fais des trucs de geek (mais je me soigne)Ce blog n'est pas sérieux mais son contenu l'est, faites bien attention !Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-9104127120136608544.post-61078540797090315842015-12-22T08:40:00.000-08:002015-12-22T08:40:30.701-08:00Utiliser ERB en c++, ou comment transformer un language sexy comme ruby en quelque-chose qui fait peur !On a beau dire, le c et le c++ sont quand même les langages les plus puissant qui existent (surtout c++ en fait), mais il sont complexes et surtout ne sont pas interprétés !<br />
<br />
Pour pallier certain manques de ces langages il est possible de rendre scriptable une application, via une api vers un langage interprété.<br />
<br />
Ici on s’intéresse au problème suivant: on veut permettre à l'utilisateur d'inclure certaines commande pour rendre dynamique un document texte qu'il éditerai depuis une application écrite en c++.<br />
<br />
J'ai cherché diverses solutions et c'est finalement Ruby qui a retenus mon attention, notamment à cause d'erb, le langage de template intégré à Ruby.<br />
<br />
Prenons un exemple simple, un petit code ruby utilisant erb pour imprimer un petit hello world:<br />
<br />
<span style="color: #9fc5e8;"><br /></span>
<span style="color: #9fc5e8;">
</span><table style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: #9fc5e8;">#!/usr/bin/ruby</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"><span style="color: #ea9999;">require</span> 'erb'</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;">my_template =<span style="color: #b6d7a8;"> "Hello World\nToday is <%# this is just a comment %> <%= MyModule.MyFunc()%>\n"</span></span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"><span style="color: #ea9999;">module</span> <span style="color: #ffe599;">MyModule</span></span><br />
<span style="color: white;"> <span style="color: #ea9999;">def</span> <span style="color: #f9cb9c;">self.</span><span style="color: #ffe599;">MyFunc()</span></span><br />
<span style="color: white;"> <span style="color: #ffe599;">Time.now.strftime</span>(<span style="color: #b6d7a8;">'%A'</span>)</span><br />
<span style="color: white;"> <span style="color: #ea9999;">end</span></span><br />
<span style="color: #ea9999;">end</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;">my_erb = <span style="color: #ffe599;">ERB.</span><span style="color: #f9cb9c;">new</span>(my_template)</span><br />
<span style="color: white;"><span style="color: #ea9999;">puts</span> my_erb.<span style="color: #ffe599;">result</span>()
</span></td></tr>
</tbody></table>
<br />
<br />
Mais maintenant, addmettons que l'on veuille faire la même chose en c++, cad au moins pouvoir créer une fonction qui puisse employer les données de nos variables c++ pour les employer dans ruby.<br />
<br />
Pour ce faire on va passer par l'API c de ruby, pour ceux qui ne connaissent pas un petit lien sur <a href="https://silverhammermba.github.io/emberb/c/" target="_blank">le tuto</a> !<br />
<br />
<br />
Le premier défis consiste à obtenir les fichiers de développement ruby, sous ubuntu 15.04 il suffit d'installer ruby-all-dev:<br />
<span style="color: #9fc5e8;"><br /></span>
<table style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;">sudo apt-get install ruby-all-dev</span></td></tr>
</tbody></table>
<span style="color: #9fc5e8;">
</span><br />
Si comme moi vous souhaitez aussi employer pkg-config il faut installer aussi ruby-pkg-config<br />
<span style="color: #9fc5e8;"><br /></span>
<table style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;">sudo apt-get install ruby-pkg-config</span></td></tr>
</tbody></table>
<span style="color: #9fc5e8;">
</span><br />
Voilà, nous sommes prêts à utiliser ruby à l'intérieur de c ou c++. Donc, ça donne quoi le script d'en dessus en c++ ?<br />
<br />
<span style="color: #b6d7a8;"><br /></span>
<table style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #b6d7a8;">#include <iostream><br />#include <ruby.h><br /><br />#include <cstdio><br />#include <ctime></span><br /><span style="color: #a2c4c9;"><br />using namespace</span> std;<br /><br /><span style="color: #9fc5e8;">const string</span> erb_line =<span style="color: #ffe599;"> "Hello World\nToday is <%# this is just a comment %><%= MyModule.MyFunc()%>\n"</span>;<br /><br />VALUE MyFunc(<span style="color: #9fc5e8;">int</span> argc, VALUE* argv, VALUE self) {<br /> <br /> time_t rawtime;<br /> tm* timeinfo;<br /> <span style="color: #9fc5e8;">char</span> buffer [80];<br /><br /> time(&rawtime);<br /> timeinfo = localtime(&rawtime);<br /><br /> strftime(buffer,80,"%A",timeinfo);<br /> <br /> <span style="color: #9fc5e8;">string</span> timeString(buffer);<br /> <br /> <span style="color: #f9cb9c;">return</span> rb_str_new2(timeString.c_str());<br /> <br />}<br /><br /><span style="color: #9fc5e8;">int</span> main(<span style="color: #9fc5e8;">int</span> argc, <span style="color: #9fc5e8;">char</span> ** argv){<br /> <br /> <span style="color: #d5a6bd;"> /* construct the VM */</span><br /> ruby_init();<br /> <br /> <span style="color: #d5a6bd;">/* Ruby goes here */</span><br /> ruby_init_loadpath();<br /> rb_require("erb");<br /> <br /> <span style="color: #d5a6bd;">// Define a new module </span><br /> VALUE mymodule = rb_define_module("MyModule");<br /> <span style="color: #d5a6bd;">//add a function to the module</span><br /> rb_define_module_function(mymodule, "MyFunc", (VALUE (*)(...)) MyFunc, -1);<br /><br /> <span style="color: #d5a6bd;">//get a reference to ERB</span><br /> ID sym_erbclass = rb_intern("ERB");<br /> VALUE erbclass = rb_const_get(rb_cObject, sym_erbclass);<br /> <span style="color: #d5a6bd;">//list of arguments to initialise erb (1 arg)</span><br /> VALUE erbargv[1];<br /> erbargv[0] = rb_str_new2(erb_line.c_str());<br /> VALUE myerb = rb_class_new_instance(1, erbargv, erbclass);<br /> <br /> <span style="color: #d5a6bd;"> //prepare the result</span><br /> VALUE resultargv[0];<br /> VALUE result = rb_funcallv(myerb, rb_intern("result"), 0, resultargv);<br /> <br /> cout << <span style="color: #9fc5e8;">string</span>(RSTRING_PTR(result), RSTRING_LEN(result));<br /><br /> <span style="color: #d5a6bd;"> /* destruct the VM */</span><br /> <span style="color: #f9cb9c;">return</span> ruby_cleanup(0);<br /> <br />}</span></td></tr>
</tbody></table>
<span style="color: #9fc5e8;">
</span><br />
Un peu plus long n'est-ce pas ? Mais ce n'est pas tant sorcier que cela, c'est juste pénible à chercher dans la doc quand on est dans un cas de figure que les gens rencontrent apparement peu et donc ne documentent guère plus.<br />
<br />
Il existe néanmoins des subtilité induite par c++, qui est par exemple plus fortement typé que c, ce qui explique qu'il faille caster de manière judicieuse le pointeur d'une fonction c++ que l'on veut enregistrer dans ruby.<br />
<br />
La compilation ne pose pas de problème majeur, le plus dur et de localiser les headers dont dépend <ruby.h> pour les inclures dans le path (ci dessous la ligne que j'ai employé sur ubuntu 15.04):<br />
<span style="color: #9fc5e8;"><br /></span>
<table style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;">g++ --std=c++11 main.cpp -o essai -I/usr/include/ruby-2.1.0 -I/usr/include/x86_64-linux-gnu/ruby-2.1.0/ -lruby-2.1 </span></td></tr>
</tbody></table>
<span style="color: #9fc5e8;">
</span><br />
Vous me direz, tant d'efforts pour pas grand chose ? Je vous rapelle que le but était de pouvoir exploiter les données contenues dans une application c++, hors vous remarquerez que MyFunc peut tout à fait servir d'accesseur ! Ainsi nous disposons de toutes les cartes pour créer des applications exploitant erb.<br />
<br />
La prochaine fois je vous montrerai comment cross-compiler une telle application pour Windows depuis Linux !<br />
Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com0tag:blogger.com,1999:blog-9104127120136608544.post-14035420731485477362015-02-09T12:57:00.004-08:002015-02-10T01:46:49.679-08:00Pourquoi je soutiens bec et ongles l'initiative pour remplacer la TVA par une taxe sur les énergies ?Pourquoi je soutiens bec et ongles l'initiative pour remplacer la TVA par une taxe sur les énergies ?<br />
<br />
<a href="http://fiscalite-ecologique.ch/dms/esm/Verfassungstext_ESM_fr.pdf" target="_blank">Le texte de l'initiative </a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.famillejospin.ch/ouvrirlesyeux/images/tetva/tva_chaperon_rouge-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.famillejospin.ch/ouvrirlesyeux/images/tetva/tva_chaperon_rouge-3.png" height="281" width="400" /></a></div>
<br />
<br />
C'est vrai que quand on me l'a présentée, je me suis dit: "mais quelle bêtise, les gens ne vont jamais vouloir d'un truc pareil." Comment j'ai changé d'avis ?
<br />
<br />
Premièrement, j'ai appris plus en détail ce qu'était la TVA. À l'époque, je savais déjà que c'était une taxe payée par les entreprises et qui se répercutait ensuite sur le prix et donc le consommateur final. Ayant fait un peu de compta, je savais déjà quel enfer pouvait être la TVA pour les comptables (comptabiliser celle qu'on a payée, celle qu'on doit payer et ce pour chaque petite opération de transformation).
<br />
<br />
Le premier scoop qu'on m'a asséné à l'époque, naïf lycéen que j'étais, c'est que toute cette complexité avait un coût: car en plus, on doit subir moult contrôles et pouvoir ensuite se justifier sur le moindre achat, et ce, pour les beaux yeux de l'État.
<br />
<br />
Le second scoop qu'on m'a asséné, c'est qu'il fallait supprimer une autre taxe pour obtenir un vrai effet incitatif avec une taxe pour l'environnement, en tout cas sur les énergies fossiles, car, il faut le savoir, la demande en énergie est passablement inélastique. Cela veut dire quoi ? Cela veut simplement dire que la demande va réagir très peu à une augmentation du prix.
<br />
<br />
Enfin, et cela je le savais déjà, les quantité disponible de pétroles sont limitée et ce, sans parler des impacts sinistrement négatifs de la consommation d'énergie non-renouvelable. (<a href="http://www.swissinfo.ch/fre/toute-l-actu-en-bref/le-giec-alerte-sur-les-risques-accrus-d-ins%C3%A9curit%C3%A9-et-de-conflits/38274604" target="_blank">Un exemple</a>)
<br />
<br />
<br />
Ok, mais pourquoi ne pas prendre une autre solution comme attendre ou une taxe en plus ?
<br />
<br />
Alors voici la liste de mes argument concernant...
<br />
<br />
attendre:
<br />
<br />
<ul>
<br />
<li>Attendre ne peut pas permettre à la situation de changer. Du pétrole ne va pas apparaître. Les énergies renouvelables arrivent également à maturité. Il est utopique de croire que l'on arrivera un jour à la même concentration énergétique que l'uranium ou le pétrole et de beaux systèmes centralisés avec le renouvelable.</li>
<br />
<li>Attendre, c'est prendre le risque toujours plus présent d'une flambée des prix du pétrole qui nous forcerait à changer en urgence.</li>
<br />
<li>Attendre, c'est relâcher plus de pollution dans l'atmosphère. Outre les effets du changement climatique, les résidus de combustion ont d'autres effets très amusants sur la santé (mais pas agréable pour nous).</li>
</ul>
<br />
<br />
Une autre taxe ? La question mérite de se poser! Pourquoi la TE serait meilleures qu'une autre ?
<br />
<br />
Hé bien justement, car elle remplace la TVA. Et donc:
<br />
<br />
<ul>
<br />
<li>Elle libère les entreprises d'un fardeau administratif. En effet le prélèvement de la TVA est coûteux: 1,8 milliards qui pèsent essentiellement sur les petites entreprises pourtant le nerf de la guerre de l'innovation.</li>
<br />
<li>Libère les entreprises d'une taxe sur le travail et l'innovation. En effet la TVA oblige à l'innovation d'être 8% plus rentable car elle pèsera sur les prix que l'innovation devra justifier (ou au contraire limitera l'effet de l'innovation pour une baisse des prix)</li>
<br />
<li>Elle ne représente qu'une redistribution plus intelligente de la facture fiscale. <b>Au final les citoyens ne paieront pas plus dans l'ensemble. Les gens ont peur que cela retombe le plus sur eux mais il ne dépend que d'eux pour s'adapter! Et comme la demande pour s'adapter va augmenter, le besoin en innovation va grandir.</b></li>
</ul>
<br />
<br />
Or, l'innovation c'est le nerf de la guerre contre le gaspillage d'énergie. J'aime me baser sur les explications contenues dans cet exposé, qui explique et démontre que la croissance aujourd'hui, on ne l'a obtenue qu'en ayant les moyens de brûler plus d'énergie à peu de choses près. Bien sûr je ne suis pas entièrement d'accord. L'efficacité énergétique a augmenté aussi et contribué à cette croissance (ainsi un gramme de CO2 émis vous apporte plus de kWh aujourd'hui qu'il y a 40 ans). Mais cela risque de s'inverser bientôt, les nouveaux type de pétroles (schiste, sables bitumineux) et l'augmentation de la part du charbon dans le mix énergétique vont faire diminuer à nouveau l'efficacité énergétique. <a href="http://www.enerzine.com/14/12938+la-decarbonisation-mondiale-assez-rapide-remise-en-cause+.html" target="_blank">Par exemple cet article en parle</a>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://ytimg.googleusercontent.com/vi/nderLmgkwus/0.jpg" frameborder="0" height="266" src="http://www.youtube.com/embed/nderLmgkwus?feature=player_embedded" width="320"></iframe></div>
<br />
Or, il y a un autre point sur lequel je ne suis pas d'accord avec lui. Si les ressources énergétiques que l'on a aujourd'hui à disposition correspondent à 200 esclaves, on ne vit pas comme si on avait 200 esclaves à notre disposition et pour cause: on gère l'énergie comme des tordus, en la gaspillant allègrement. Les prochaines opportunités de croissance, à vrai dire celles qu'il nous reste, sont dans l'innovation pour l'efficacité énergétique et les énergies renouvelables. Si on gère correctement notre système économique pour ne pas gaspiller l'énergie que l'on y fait entrer alors on pourra encore croître là dessus.
<br />
<br />
Par contre, je pense que le risque d'avoir des guerres de l'énergie ou des camps de l'horreur en tout genre avec des réfugiés climatiques n'est pas à exclure. Il n'y a qu'à voir ce qui s'est passé en Irak. Rendre la suisse autonome n'en sera que plus sûr.
<br />
<br />
Au final les arguments des opposants, bien qu’apparemment convaincants sont soit des mensonges, soit du manque d'information.
<br />
<br />
Prenons le cas de l'essence annoncée à 5 francs suisses ! Selon les chiffre de 2013 de l'OFEN, en suisse ont été utilisées comme énergies non renouvelables
<br />
<ul>
<br />
<li>10'900'000 tonnes de produits pétroliers divers soit 109'000'000'000 kWh</li>
<br />
<li>59'300'000'000 kWh d'électricité dont 40% non ENR soit 23'720'000'000 kWh</li>
<br />
<li>33'600'000'000 kWh sous forme de gaz soit 33'600'000'000 kWh</li>
</ul>
<br />
<br />
soit 166'320'000'000 kWh, avec 21 mia de francs de rentrée fiscale pour la TVA le prix du kWh augmenterai de 12.626 centimes. Le prix de l'essence ne grimperait que de 1.20 chf (et encore à déduire la TVA actuelle soit en réalité à peine 1.10 d'augmentation).
<br />
<br />
L'idée étant que si la taxe passe, du jour au lendemain le prix de l'essence grimperai à 5 chf... hahaha, ils me font rire. S'il grimpait aussi haut la consommation d'énergie fossile aurait été divisée par plus de 2. Mis à part le fait que la situation serai radicalement différente et que donc il est dur d'imaginer où l'on en sera à ce moment là, cela n'arrivera pas avant de nombreuses années. En effet la demande de combustible fossile est très inélastique et donc varie peu et lentement suite à un changement de prix important.
<br />
<br />
Et quand on y sera arrivé, le tournant énergétique sera tellement bien engagé que l'on pourra sans problème replacer la TE par autre chose. Personnellement j'aimerai bien adapter l'idée (qui est bien foutue) aux produits écotoxiques qui empoissonnent notre environnement (à tout hasard).<br />
<br />
S'il suffisait d'introduire une taxe pour que l'effet soit immédiat (ou quasi immédiat) la gestion des états en serait grandement facilitée !
<br />
<br />
<br />
En claire une idée bonne quoique déstabilisante, combattue par la peur et le mensonge ! Personnellement j'espère que cela va passer. Pour que vous puissiez continuer de vous faire une opinion je vous invite à continuer sur <a href="http://www.famillejospin.ch/ouvrirlesyeux" target="_blank">ce blog qui est un peu plus détaillé</a>.
<br />
<br />Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com1tag:blogger.com,1999:blog-9104127120136608544.post-57709092444084397562014-11-24T11:40:00.002-08:002014-11-24T11:40:28.129-08:00[retour de convention] les 27èmes rencontres du club pythagoreAlors je serai bref au niveau du texte j'ai (et surtout mon ordinateur, qui a ramé pendant 12h ^^ ) assez travaillé sur la video souvenir ;P<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/HGUB8oVquiY?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
Néanmoins une petite explication s'impose quand même du coup...<br />
<br />
Les rencontres du club pythagore sont une sympathique convention avec pas trop de monde, un super buffet et une super ambiance qui se déroule à Provin. Nous étions invités avec l'équipe la Chaux-de-Fonds 1904 à venir présenter notre jeu. J'ai donc fait jouer deux parties de crimes le samedis la première étant allé comme sur des roulettes, j'étais très en forme et es joueurs bien dans l'ambiance, la seconde un peu plus dur car joué tard le soir.<br />
<br />
De plus, durant la première partie... ils ont finis par faire ce que tout le monde attendais mais chut... demandez moi de vous faire jouer le scénario plutôt que je ne vous le spoil ^^<br />
<br />
Le dimanche je me suis essayé à friponnes (le JDR est encore en dévellopement, mais vous trouverez des livres dans cet univers sur <a href="http://libreterre.fr/" target="_blank">ce site</a>). Personnellement je me suis éclaté. Le jeu se base sur le système FU qui est à la fois littéral et léger. Les joueurs ont une très grande influence sur le mode de résolution du scénario, ce qui approche le jeu d'un système narratif, mais avec un système classique et peu rebutant pour les habitués de JDR "Canoniques".<br />
<br />
Je dirai donc que j'ai tellement rigolé (j'ai crus que j'allais me casser les côtes aux moments les plus croustillants), que les morpions peuvent êtres une arme de destruction massive et que je n'en dirai pas plus... bandes d'indiscrets fripons curieux ;P<br />
<br />
Bon, après le jeu ne bat largement pas Romance Érotique au point de vue des détails si ça peut vous rassurer... il n'est juste pas à faire jouer au personnes de moins de 16 ans (pire encore si on joue avec des lustucrus plus vieux qui n'ont pas de retenue ;P )<br />
<br />
Mais je vous le recommande si vous aimez les jeux légers où l'on ne se prends pas trop la tête!Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com1tag:blogger.com,1999:blog-9104127120136608544.post-38596901124958195812014-05-12T12:40:00.003-07:002014-05-12T12:42:49.183-07:00Chimériades!Je serai pas le seul à faire un compte rendu des chimériades. Pour les amateurs de longs discours je vous renvoie au post d'Alias, qui a écrit plus de 1000 signes et que je ne vais en aucun cas imiter ;P<br />
<br />
<a href="http://alias.codiferes.net/wordpress/index.php/chimeriades-2014/?fb_action_ids=10152167241088865&fb_action_types=news.publishes&fb_ref=pub-standard&fb_source=aggregation&fb_aggregation_id=288381481237582">http://alias.codiferes.net/wordpress/index.php/chimeriades-2014/?fb_action_ids=10152167241088865&fb_action_types=news.publishes&fb_ref=pub-standard&fb_source=aggregation&fb_aggregation_id=288381481237582</a><br />
<br />
Comme en plus mon appareil photo est bientôt totalement knock out je l'ai pas pris, cette année je me suis ramené avec ma caméra et donc ce message n'a d'autre but que de partager avec vous le montage que j'ai obtenu:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/AZmbOPwKUjA?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
Le lien pour la musique: <a href="http://www.jamendo.com/fr/artist/370191/wizart-music">http://www.jamendo.com/fr/artist/370191/wizart-music</a><br />
<br />
En passant j'ai gagné un JDR sur cette conv, je crois que je vais réaliser ma première critique sur ce blog (dès que j'aurais le temps ^^ )!<br />
<br />
<br />
Et surtout! Un immense merci au orgas: elle est géniale votre conv!<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com1tag:blogger.com,1999:blog-9104127120136608544.post-3806463757283512232014-03-25T14:06:00.003-07:002014-03-25T14:06:46.177-07:00[retour à froid] LudescoIl y a un truc que je n'aime pas avec les conv... c'est le besoin de se remettre à jour après coup! Ça fait 2 semaines que ludesco et terminé et j'ai toujours pas fait de retour... par nécessité scolaire.<br />
<br />
Maitenant que j'ai un peu de temps (ce qui explique que ce message soit rédigé à 10h du soir) juste un rapide retour.<br />
<br />
C'était ma première année dans le comité, petit jeune de service (comme d'hab ^^ ) et resp JDR. J'ai d'ailleurs pas eu beaucoup de temps pour faire des jeux de plateaux, occupés que j'étais à courir partout pour les JDR.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMKuH1VHChm3E78xZZ_g_CIy1IxlrGRT6brGFYKwL-9A6IbQYAx09_mQm-mcdkDJ4z5t0MN08dg5nQwuCZytS7dzpPPpM7cN3O8q76DqnggqP8lb6f4hK1qJZYrRnHUvDrJDDP9kDd/s1600/P1110704_sml.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMKuH1VHChm3E78xZZ_g_CIy1IxlrGRT6brGFYKwL-9A6IbQYAx09_mQm-mcdkDJ4z5t0MN08dg5nQwuCZytS7dzpPPpM7cN3O8q76DqnggqP8lb6f4hK1qJZYrRnHUvDrJDDP9kDd/s1600/P1110704_sml.JPG" height="300" width="400" /></a></div>
<br />
<br />
Mais ça en valait la peine. Pour le 5ème anniversaire on a eu un programme JDR étoffé comme jamais. Et la sortie du jeu la Chaux-de-Fonds 1904 est venue couronné le tout (pour ceux qui l'auraient pas encore obtenu... contactez moi si vous avez mon adresse et sinon regarder dans votre magasin de jeu préféré et même dans votre librairie, le jeu devrait y arriver tantôt s'il n'y est pas déjà!).<br />
<br />
Ha oui, aussi de superbe partie au musée d'histoire naturelle, la convention avance ses pions dans le domaine du "JDR à valeur ajoutée". Un concept que j'adore personnellement! Mais comme il est tard et que j'en ai marre d'écrire je vous donne juste la photo:<br />
<br />
<span id="goog_2142432173"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiryMQG0MFj3tmclst36Pf25BfKCf_oZ_en6G2ju3qB-8xLOeHq6XxXZN3qoUF0P1SHc2iAA92tXh81wP2m30vDYU95yNZaaYvLl2eqGziVhhQeCieb8SlQzjm_dXKEUud85vkhIMK/s1600/P1110666_sml.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiryMQG0MFj3tmclst36Pf25BfKCf_oZ_en6G2ju3qB-8xLOeHq6XxXZN3qoUF0P1SHc2iAA92tXh81wP2m30vDYU95yNZaaYvLl2eqGziVhhQeCieb8SlQzjm_dXKEUud85vkhIMK/s1600/P1110666_sml.JPG" height="300" width="400" /></a></div>
<br class="Apple-interchange-newline" /><br />
Bien ludiquement et à l'année prochaine (du 13 au 15 mars)Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com0tag:blogger.com,1999:blog-9104127120136608544.post-49802398845082642202014-01-22T03:41:00.000-08:002014-01-22T03:41:40.889-08:00Ludesco c'est bien, mais combien bien?Hello, dsl de ne pas faire démarrer ce blog au quart de tour, il me tiens à coeur mais je manque de temps (vous allez bientôt savoir pourquoi). Mais bon, j'ai une bonne occasion puisqu'il se prépare de part chez moi une super convention de jeu en tout genre: <a href="http://www.ludesco.ch/" target="_blank">Ludesco</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhor3pSdXUZ8TtICT_PUOMQ73OxXYUWDPId_yckmdasI4vj7-sdbeCa6OgVPy0zPCkzZQw6N1incwkSc6ZtcKEtDOJAFkK1vFqK_gnUxKpssbNioT856UCHxJSY26xdDG5gNU-QZyS_/s1600/slideabc.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhor3pSdXUZ8TtICT_PUOMQ73OxXYUWDPId_yckmdasI4vj7-sdbeCa6OgVPy0zPCkzZQw6N1incwkSc6ZtcKEtDOJAFkK1vFqK_gnUxKpssbNioT856UCHxJSY26xdDG5gNU-QZyS_/s1600/slideabc.jpg" height="225" width="400" /></a></div>
<br />
<br />
Ludesco faut y venir, c'est bien! Mais comme je vous vois sceptique et que vous et moi aimons les chiffres je vais essayer de répondre à la question "combien c'est bien?"<br />
<br />
Après de très longue recherches nous sommes enfin parvenu à mettre sur pied un modèle pour compter combien Ludesco sera bien.<br />
<br />
Implémenté en c++ cela donne (cclcb veut dire "pour compter combien Ludesco c'est bien!" ):<br />
<br />
<table cellpadding="20" style="background-attachment: scroll; background-color: black; background-image: none; background-position: 0% 0%; background-repeat: repeat repeat; width: 100%;"><tbody>
<tr><td><span style="color: white;"> <span style="color: #ea9999;">unsigned int</span> </span><span style="color: #f9cb9c;">cclcb</span><span style="color: white;">(</span><span style="color: #ea9999;">unsigned int</span><span style="color: white;"> </span><span style="color: white;">annee,</span><span style="color: white;"> </span><span style="color: #ea9999;">unsigned int</span><span style="color: white;"> </span><span style="color: white;">scoreInitial = 2){</span><br />
<span style="color: white;"><br /></span><span style="color: white;"> <span style="color: #b6d7a8;">if</span>(annee){</span><br />
<span style="color: #b6d7a8;"> </span><span style="color: white;"> </span><span style="color: #b6d7a8;">if</span><span style="color: white;">(</span><span style="color: white;">scoreInitial</span><span style="color: white;">)</span><br />
<span style="color: white;"> </span><span style="color: white;"> </span><span style="color: white;"> </span><span style="color: #ffe599;">return</span><span style="color: white;"> </span><span style="color: #f9cb9c;">cclcb</span><span style="color: white;">(</span><span style="color: white;">annee-1,</span><span style="color: white;"> </span><span style="color: #f9cb9c;">cclcb</span><span style="color: white;">(</span><span style="color: white;">annee,</span><span style="color: white;"> </span><span style="color: white;">scoreInitial-1)</span><span style="color: white;">)</span><span style="color: white;">;</span><br />
<span style="color: white;"> </span><span style="color: white;"> </span><span style="color: #b6d7a8;">else</span><br />
<span style="color: white;"> </span><span style="color: white;"> </span><span style="color: white;"> </span><span style="color: #ffe599;">return</span><span style="color: white;"> </span><span style="color: #f9cb9c;">cclcb</span><span style="color: white;">(</span><span style="color: white;">annee-1, 1</span><span style="color: white;">);</span><br />
<span style="color: white;"> }</span><br />
<span style="color: white;"> <span style="color: #b6d7a8;">else</span></span><br />
<span style="color: white;"> <span style="color: #ffe599;">return</span> </span><span style="color: white;">scoreInitial+1</span><span style="color: white;">;</span><br />
<br />
<span style="color: white;">}</span></td></tr>
</tbody></table>
<br />
Sans entrer dans les détails on recalcule récursivement le score de l'année en cour avec le score de l'année passée et une estimation du score de l'année en cour (qui est calculée récursivement et vaut au minimum 1. Pour ceux qui avaient pas remarqué cela correspond à la <a href="http://jm.davalan.org/mots/suites/ack/index.html" target="_blank">fonction d'Ackermann</a>.<br />
<br />
Bon, visiblement ceux qui voulaient des chiffres sont servis, pour les autres qui on pas tiqué je vous invite à lire <a href="http://fr.wikipedia.org/wiki/Fonction_d'Ackermann" target="_blank">cette article de wikipédia</a>, juste ce qui faut pour frimer au repas de noël. Bien sûr les auteurs originaux de la fonction ne se doutaient pas qu'elle servirait un jour à estimer la qualité d'un événement exceptionnel!<br />
<br />
Et en plus je suis dans l'équipe des JDR*, alors restez branchés parce qu'il va falloir trouver des MJ et des joueurs pour une année encore plus exceptionnelle que les précédentes (la 5ème si vous voulez essayer le calcul)! Plus de détails bientôt!<br />
<br />
<i>*si si, c'est entre autre pour ça que je n'ai pas beaucoup de temps, mais c'est tellement cool que je me pardonne ^^</i>Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com0tag:blogger.com,1999:blog-9104127120136608544.post-79125436909094000932013-08-28T03:19:00.000-07:002013-08-28T03:19:47.257-07:00Question de bits et de bytesMis à part que les pionniers de l’informatique auraient dut se préoccuper du français quand ils ont nommée leurs unités logique voici le problème que je me posais initialement:<br />
<br />
Un booléen est habituellement stocké dans un octet (soit un unsigned char) alors qu'il ne peut prendre que deux états. Pour un seul booléen ou des milliers des booléens ça reste un gaspillage acceptable sur les ordinateurs modernes, où la mémoire ne manque pas. Mais pour certaines applications (par exemples de larges <a href="http://fr.wikipedia.org/wiki/Filtre_de_Bloom" target="_blank">filtres de Bloom</a>) il est souhaitable de compacter la place occupées par les milliers de booléens que l'on veut instancier. En d'autre thermes, peut-on instancier un tableau de bits?<br />
<br />
Réponse, pas de base, il faut quitter sa zone de confort avec les jolis opérateur qu'on nous a appris en primaire ( + - ÷ × ) et s'attaquer à ces inquiétant opérateur dit bit à bit <span style="font-size: xx-small;">(et il est interdit de penser à une partouze) </span>( & | ^ << >> ).<br />
<br />
Heureusement ce tutoriel est là pour vous aider, on va même réaliser ensemble un jolis objet c++ qui va gérer tout ça pour nous! Voyons d'abords ces fameux opérateurs qu'on va utiliser:<br />
<br />
<h4>
&</h4>
AND, "et" logique, renvoie un bit à 1 si et seulement si les deux bits de même poids valent 1 sur les deux paramètres passés:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;">unsigned int</span> a = 4 & 7; <span style="color: #666666;">//a = 4</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> b = 7 & 9; <span style="color: #666666;">//b = 1</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> c = 4 & 9; <span style="color: #666666;">//c = 0</span></span><br />
<br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> oct = 0203 & 0205; <span style="color: #666666;">//oct = 0201</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> hex = 0x000F02 & 0x00420F; <span style="color: #666666;">//hex = 0x000202;</span></span></td></tr>
</tbody></table>
<br />
<br />
Vous l'aurez remarqué la clé du problème c'est la décomposition des nombre en puissance de deux. Pour accéder au nième bit d'un entier il suffit donc de réaliser nombre & (2 à la puissance n).<br />
<br />
<h4>
|</h4>
OR, "ou" simple fonctionne de la même manière mais il lui suffit qu'il seul des deux bits de même poids soient à 1 pour renvoyer 1:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;">unsigned int</span> a = 4 | 7; <span style="color: #666666;">//a = 7</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> b = 7 | 9; <span style="color: #666666;">//b = 15</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> c = 4 | 9; <span style="color: #666666;">//c = 13</span></span><br />
<br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> oct = 0203 | 0205; <span style="color: #666666;">//oct = 0207</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> hex = 0x000F02 | 0x00420F; <span style="color: #666666;">//hex = 0x004F0F;</span></span></td></tr>
</tbody></table>
<br />
<br />
<h4>
^ </h4>
XOR, "ou" exclusif, renvoie 1 si et seulement si un seul des bits de même poids vaut 1:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;">unsigned int</span> a = 4 ^ 7; <span style="color: #666666;">//a = 3</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> b = 7 ^ 9; <span style="color: #666666;">//b = 14</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> c = 4 ^ 9; <span style="color: #666666;">//c = 13</span></span><br />
<br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> oct = 0203 ^ 0205; <span style="color: #666666;">//oct = 0006</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> hex = 0x000F02 ^ 0x00420F; <span style="color: #666666;">//hex = 0x004C0C;</span></span></td></tr>
</tbody></table>
<br />
<br />
<h4>
<< et >> </h4>
représentent un décalage à gauche ou à droite ce qui revient à multiplier ou diviser par deux autant de fois que spécifié ( et dans la limite de la taille du type utilisé).<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;">unsigned int</span> a = 2 << 2; <span style="color: #666666;">//a = 8</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> b = 1 << 3; <span style="color: #666666;">//b = 8</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> c = 2 >> 1; <span style="color: #666666;">//c = 1</span></span></td></tr>
</tbody></table>
<br />
<br />
Leur principale utilité, combinés aux opérateurs précédents, est d'accéder à un bit donné.<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;">unsigned int</span> a = 1 << 0; <span style="color: #666666;">//a permet d'inspecter le bit 0</span></span><br />
<span style="color: white;"><span style="color: #ea9999;">unsigned int</span> b = 1 << 5; <span style="color: #666666;">//b permet d'inspecter le bit 5</span></span></td></tr>
</tbody></table>
<br />
Il fut un temps les processeurs ne pouvaient pas réaliser directement les opérations arithmétiques de base, il fallait les implémenter grâce à ces opérateurs bits à bits. Par exemple le bon vieil algorithme d'addition en colonne devenait (la représentation assumée est celle dite complément à deux, la charge de détecter les dépassements n'est pas assumée par la fonction):<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"> <span style="color: #ea9999;">int</span> <span style="color: #f9cb9c;">additionner</span> (<span style="color: #ea9999;">int</span> pN1, <span style="color: #ea9999;">int</span> pN2){</span><br />
<br />
<span style="color: white;"> <span style="color: #ea9999;">int</span> n1 = pN1;</span><br />
<span style="color: white;"> <span style="color: #ea9999;">int</span> n2 = pN2;</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"> <span style="color: #ea9999;">int</span> r1 = n1 ^ n2;<span style="color: #666666;"> //addition directe</span></span><br />
<span style="color: white;"> <span style="color: #ea9999;">int</span> r2 = (n1 & n2) << 1; <span style="color: #666666;">//retenue</span></span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"> <span style="color: #b6d7a8;">if</span>(!r1)</span><br />
<span style="color: white;"> <span style="color: #ffe599;">return</span> r2;</span><br />
<span style="color: white;"> <span style="color: #b6d7a8;">else if</span> (!r2)</span><br />
<span style="color: white;"> <span style="color: #ffe599;">return</span> r1;</span><br />
<span style="color: white;"> <span style="color: #b6d7a8;">else</span></span><br />
<span style="color: white;"> <span style="color: #ffe599;">return</span> <span style="color: #f9cb9c;">additionner</span> (r1, r2);</span><br />
<br />
<span style="color: white;">}</span></td></tr>
</tbody></table>
<br />
<br />
Donc on peut s'offrir un tableau de booléen compressé, voici en c++:<br />
<br />
Définition:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"> <span style="color: #ea9999;">class</span> <span style="color: #f9cb9c;">BinaryKeeper</span>{</span><br />
<span style="color: white;"><br /> <span style="color: #a2c4c9;">public:</span></span><br />
<span style="color: white;"><br /> <span style="color: #666666;">/** Default constructor */</span><br /> <span style="color: #f9cb9c;">BinaryKeeper</span>(<span style="color: #ea9999;">unsigned int</span> pSize);<br /> <span style="color: #666666;">/** Default destructor */</span><br /> <span style="color: #ea9999;"> virtual</span> <span style="color: #f9cb9c;">~BinaryKeeper</span>();<br /> <span style="color: #666666;">/** Copy constructor<br /> * \param other Object to copy from<br /> */</span><br /> <span style="color: #f9cb9c;">BinaryKeeper</span>(<span style="color: #ea9999;">const BinaryKeeper&</span> other);<br /> <span style="color: #666666;">/** Access size<br /> * \return The current value of size<br /> */</span><br /> <span style="color: #ea9999;">unsigned int</span> <span style="color: #f9cb9c;">Getsize</span>() <span style="color: #f9cb9c;">const</span>{ <span style="color: #ffe599;">return</span> size; }<br /><br /> <span style="color: #ea9999;">bool</span> <span style="color: #f9cb9c;">InIndex</span>(<span style="color: #ea9999;">unsigned int</span> index) <span style="color: #f9cb9c;">const</span>;<br /> <span style="color: #ea9999;">char</span> <span style="color: #f9cb9c;">CharInIndex</span>(<span style="color: #ea9999;">unsigned int</span> index) <span style="color: #f9cb9c;">const</span>;<br /><br /> <span style="color: #ea9999;">void</span> <span style="color: #f9cb9c;">SetIndex</span>(<span style="color: #ea9999;">unsigned int</span> index, <span style="color: #ea9999;">bool</span> pState);</span><br />
<span style="color: white;"><br /> <span style="color: #a2c4c9;">private:</span></span><br />
<span style="color: white;"><br /> <span style="color: #ea9999;"> unsigned int</span> size; <span style="color: #666666;">//!< Member variable "size"</span><br /> <span style="color: #ea9999;"> unsigned char*</span> datas; <span style="color: #666666;">//!< Member variable "datas"</span></span><br />
<span style="color: white;"><br />}; </span></td></tr>
</tbody></table>
<br />
<br />
Premièrement le constructeur, il va essentiellement instancier un tableau d'unsigned char et le remplir de 0. Ce type offre l'avantage d'être de taille constantes selon les systèmes:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #666666;">/** Default constructor */</span></span><span style="color: white;"><span style="color: white;"><span style="color: #f9cb9c;"> </span></span></span><br />
<span style="color: white;"><span style="color: white;"><span style="color: #f9cb9c;">BinaryKeeper</span></span>::<span style="color: #f9cb9c;">BinaryKeeper</span>(<span style="color: #ea9999;">unsigned int</span> pSize){</span><br />
<span style="color: white;"><br /> <span style="color: #666666;">//ctor</span><br /><br /> size = pSize;<br /> <span style="color: #ea9999;">unsigned int</span> cSize = size/8 + 1;<br /><br /> <span style="color: #b6d7a8;">try</span>{<br /><br /> datas = <span style="color: #a2c4c9;">new</span> <span style="color: #ea9999;">unsigned char</span> [cSize];<br /><br /> <span style="color: #b6d7a8;">for</span>(<span style="color: #ea9999;">unsigned int</span> k = 0; k < </span><span style="color: white;"><span style="color: white;">cSize</span>; k++){<br /> datas[k] = 0;<br /> }<br /><br /> }<span style="color: #b6d7a8;">catch</span> ( <span style="color: #f9cb9c;">const std</span>::<span style="color: #ffe599;">bad_alloc</span> & ) { <span style="color: #666666;">// erreur d'allocatation.</span><br /><br /> <span style="color: #a2c4c9;">delete []</span> datas;<br /> size = 0;<br /><br /> }<br /> </span><br />
<span style="color: white;">}</span></td></tr>
</tbody></table>
<br />
Ce code n'est pas très compliqué. Notez bien que pour être certain d'avoir assez de place pour inscrire le nombre de bits demandé qui n'est pas forcément un multiple de 8 vous devez ajouter un octet à la taille de votre tableau. Si ce dépassement anecdotique vous ennuie vous pouvez corriger size, personnellement j'alloue quelques bit de plus mais je tiens à ce que mon objet encapsule la taille demandée.<br />
<br />
Le destructeur lui, va juste libérer les allocations dynamiques:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #666666;">/** Default constructor */</span></span><span style="color: white;"><span style="color: white;"><span style="color: #f9cb9c;"> </span></span></span><br />
<span style="color: white;"><span style="color: white;"><span style="color: #f9cb9c;">BinaryKeeper</span></span>::<span style="color: #f9cb9c;">~BinaryKeeper</span>(){</span><br />
<span style="color: white;"><br /> <span style="color: #666666;">//dtor</span></span><span style="color: white;"><span style="color: #666666;"></span></span><span style="color: white;"><span style="color: #a2c4c9;"> </span></span><br />
<br />
<span style="color: white;"><span style="color: #a2c4c9;"> delete []</span> datas;<br /> </span><br />
<span style="color: white;">}</span></td></tr>
</tbody></table>
<br />
<br />
Viennent ensuite les accesseurs, si accéder à une char donnée se fait de manière simple (libre à vous de définir un comportement quand vous dépasser la taille du tableau, personellement dans ce cas je renvoie le plus haut indice disponible). Pour accéder à l'état (true | false) d'un bit donné ça se corse un peu.<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;"><span style="color: white;"><span style="color: #ea9999;">char</span> <span style="color: #f9cb9c;">BinaryKeeper</span>::<span style="color: #ffe599;">CharInIndex</span>(<span style="color: #ea9999;">unsigned int</span> index) <span style="color: #ffe599;">const</span>{<br /><br /> <span style="color: #b6d7a8;">if</span> (index <= size/8)<br /> <span style="color: #ffe599;">return</span> datas[index];<br /> <span style="color: #b6d7a8;"> else</span><br /> <span style="color: #ffe599;">return</span> </span></span></span><span style="color: white;"><span style="color: #ea9999;"><span style="color: white;"><span style="color: white;"><span style="color: #ea9999;"><span style="color: white;">datas[size]</span></span></span>;</span><span style="color: white;"><br />}</span><span style="color: white;"></span><br /><br />bool</span> <span style="color: #f9cb9c;">BinaryKeeper</span>::<span style="color: #ffe599;">InIndex</span>(<span style="color: #ea9999;">unsigned int</span> index) <span style="color: #ffe599;">const</span>{<br /><br /> <span style="color: #ea9999;">unsigned int</span> i = index;<br /><br /> <span style="color: #b6d7a8;">if</span>( i >= size)<br /> i = size-1;<br /><br /> <span style="color: #ea9999;">unsigned int</span> cIndex = i >> 3 ;<br /> <span style="color: #ea9999;">unsigned int</span> cInside = i & 7 ;<br /><br /> <span style="color: #ea9999;">unsigned char</span> v = datas[cIndex];<br /><br /> <span style="color: #ea9999;">unsigned char</span> c = 1 << cInside;<br /><br /> <span style="color: #ffe599;">return</span> (bool) (v & c);<br /><br />}</span><span style="color: white;"></span></td></tr>
</tbody></table>
<br />
Les index de notre tableau de bits fonctionnent comment ceux d'un tableau classique. Le premier bit est le bit de poids 0 (2^0) du char 0. Le dernier est donc le size-1 ème bits. On corrige donc l'index s'il est trop haut (on pourrait aussi lancer une exception, renvoyer faux ou vrai par défaut ... ).<br />
<br />
Ensuite viennent ces deux lignes assez mystérieuses (je vous aide un peu et vous donne les équivalents classiques):<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"> <span style="color: #ea9999;">unsigned int</span> cIndex = i >> 3 ;<br /> <span style="color: #ea9999;">unsigned int</span> cInside = i & 7 ;</span><span style="color: white;"></span><span style="color: white;"><br /></span><span style="color: white;"></span><span style="color: white;"><br /></span><span style="color: white;"></span><span style="color: white;"> <span style="color: #666666;"> //équivalent:</span><br /> </span><span style="color: white;"><br /> <span style="color: #ea9999;">unsigned int</span> cIndex = i / 8 ;<br /> <span style="color: #ea9999;">unsigned int</span> cInside = i % 8 ;</span></td></tr>
</tbody></table>
<br />
cIndex est le char que l'on va inspecter, cInside le poids du bit à inspecter à l'intérieur. On les obtient le plus logiquement du monde en divisant par 8 et en prenant le modulo par 8 de l'indice demandé. Mais comme 8 est une puissance de 2 il y a plus "simple" (du moins en temps de calcul pour l'ordinateur). Diviser par 8 revient à diviser par 2^3 soit de décaler 3 fois à droite. Prendre le modulo revient à effacer tout les bits sauf ceux de poids 0, 1 et 2 ce qui se fait grâce à l'opérateur & 7.<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;">unsigned char</span> c = 1 << cInside;</span></td></tr>
</tbody></table>
<br />
c servira à accéder au bit souhaité. Ce que l'on fait à la ligne suivante grâce à &:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ffe599;">return</span> (bool) (v & c);</span></td></tr>
</tbody></table>
<br />
<br />
Enfin détaillons la fonction de changement d'état d'un bit donné, j'ai choisi volontairement de créer une fonction qui change le bit vers un état spécifié mais il serait possible d'en créer une qui inverse simplement l'ancien état:<br />
<br />
<table cellpadding="20" style="background: none repeat scroll 0% 0% black; width: 100%;"><tbody>
<tr><td><span style="color: white;"><span style="color: #ea9999;">void</span> <span style="color: #f9cb9c;">BinaryKeeper</span>::<span style="color: #ffe599;">SetIndex</span>(<span style="color: #ea9999;">unsigned int</span> index, <span style="color: #ea9999;">bool</span> pState) {</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"> <span style="color: #ea9999;">unsigned int</span> i = index;</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"> <span style="color: #b6d7a8;">if</span>( i >= size)</span><br />
<span style="color: white;"> i = size-1;</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"> <span style="color: #ea9999;">unsigned int</span> cIndex = i >> 3 ;</span><br />
<span style="color: white;"> <span style="color: #ea9999;">unsigned int</span> cInside = i & 7 ;<br /><br /> <span style="color: #ea9999;">unsigned char</span> c = 1 << cInside;</span><br />
<span style="color: white;"><br /></span>
<span style="color: white;"> <span style="color: #b6d7a8;">if</span> (pState){ <span style="color: #666666;">// si on veut mettre l'état à true</span></span><br />
<span style="color: white;"> datas[cIndex] |= c; <span style="color: #666666;">//alors on le met à 1</span></span><br />
<span style="color: white;"> } <span style="color: #b6d7a8;">else</span> { <span style="color: #666666;">// si on veut mettre l'état à false;</span></span><br />
<span style="color: white;"> c ^= 255;<span style="color: #666666;"> //on place un zéro sur le bit du poids qui nous intéresse.</span></span><br />
<span style="color: white;"> datas[cIndex] &= c;<span style="color: #666666;"> //on le met à 0.</span></span><br />
<span style="color: white;"> }</span><br />
<span style="color: white;">}</span></td></tr>
</tbody></table>
<br />
<br />
Bien sûr cet objet reste relativement simple dans sa conception, il ne gère pas d'exceptions, ne permet pas d'utiliser d'itérateurs, etc... Néanmoins il réalise son travail correctement (du moins de ce que j'ai put tester) quand il s'agit de gérer un filtre de bloom ou un très grands tableau de booléens tout en économisant la mémoire. Il sera par contre légèrement plus lent qu'un simple bool*.<br />
<br />
Libre à vous de l'améliorer, perso je ne le ferai que si j'en ai l'utilité. Puisque pour l'instant il me convient ainsi!Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com0tag:blogger.com,1999:blog-9104127120136608544.post-1223903478687673502013-08-28T02:46:00.000-07:002013-08-28T02:46:57.245-07:00Who Am I ?Je ne suis pas un geek, pas du moins selon la définition qui a été choisie expressément par des gens malheureux de ne rien comprendre à l'informatique:<br />
<br />
<table class="WRD"><tbody>
<tr class="odd"><td class="FrWrd"><b>geek</b> <i class="POS2">n</i></td><td><i class="Fr2">pejorative</i> (socially unskilled person) <i class="To2">familier</i></td><td class="ToWrd">boulet, tocard, blaireau <i class="POS2">nm</i></td></tr>
<tr class="odd"><td></td><td class="To2"><br /></td><td class="ToWrd">gros coincé, <b>intello coincé </b><i class="POS2">nm</i></td></tr>
<tr class="gold"><td></td><td class="To2"><br /></td><td class="ToWrd">nul, nulle <i class="POS2">n</i></td></tr>
</tbody></table>
<br />
traduction par <a href="http://www.wordreference.com/">http://www.wordreference.com</a><br />
<br />
En clair je ne suis ni un blaireau coincé, ni un intello au sens péjoratif. Par contre je fais certains trucs de geek (mais je me soigne... aussi bien que je peux):<br />
<br />
<b>Comment je me soigne: </b>avec des méthodes inattendues !<br />
<br />
<b>Pourquoi j'en parle:</b> ça fait une psychanalyse gratuite!<br />
<br />
<br />
<h2>
Programmer:</h2>
<hr />
<br />
Personnellement mon langage fétiche est le c++ pour la programmation en ligne de commande et le Java pour les programmes graphiques. Je suis néanmoins un touche à tout puisque je maîtrise également le php (et les classiques html et cie) et le ruby.<br />
<br />
<b>Comment je me soigne: </b>en programmant des choses compliquées... comme ça on arrête de vous prendre pour un geek. On vous prend pour un vrai informaticien ^^.<br />
<br />
<b>Pourquoi j'en parle:</b> de nos jours on utilise de plus en plus les nouvelles technologies. Il est donc important (selon moi) de transférer le savoir sur leur fonctionnement.<br />
<br />
<br />
<h2>
Du jeu de rôle:</h2>
<hr />
<br />
En fait essentiellement le jeu de rôle sur table. Je me suis aussi intéressé à ce que l'on nomme le grandeur nature, mais malheureusement je ne me suis pas encore tant impliqué.<br />
<br />
<b>Comment je me soigne: </b>je marque ma préférence pour les JDR plus "narratifs"! Comme ça on vous prends non plus pour un geek mais pour un futur écrivain ^^.<br />
<br />
<b>Pourquoi j'en parle:</b> simplement une activité sociale et sans compétition malsaine mérite qu'on en parle.<br />
<br />
<br />
<h2>
Mission sauvetage de la terre et ineptie politique:</h2>
<hr />
<br />
En politique je suis assez clairement vert (avec néanmoins des nuances de kaki, vert clair et turquoise voir verre de terre). Pour le reste je serais socio-libéral avec des tendances natio-communo-démocrato-anarchistes. Je vous rassure, je vous emmerderai le moins possible avec mes convictions, ce que j'aime c'est présenter les choses d'une manière originale.<br />
<br />
<b>Comment je me soigne: </b>au vu de ce qui est écrit au dessus on dira que je n'ai plus aucune chance ^^.<br />
<br />
<b>Pourquoi j'en parle:</b> parce que les raisonnements trops simples de certains populistes de tout bords me rendent nerveux! Et quand je suis nerveux faut que je parle.<br />
<br />Anonymoushttp://www.blogger.com/profile/12184939028354795147noreply@blogger.com0