[tutorial] Les opérateurs binaires

Répondre
Partager Rechercher
John... arrrrg... Promets moi, john... Johnnnnnn... *keuf, keuf, arrrk*... pro...promets moi... Tu diras à thérèse que je l'aime... Tu lui diras, hein john ? Johnnnnnnn... arrrrrrrrrrrrrrg... Unv vie consacrée à boole... Wo putains là j'ai les booles... Mourrir comme ça.... *keuf,keuf* ... comme un chien... Foutus flics de mes deux... Boolzébuth, mon âme est à toiiiii.... Arrrrgloglurbglirpkrurs. *expire en crachant son sang*
Bon je vous arrete la pour en revenir au sujet principal : le binaire et les opérateurs booléens. J'avais promis une application dans neverwinter, en voila une.
Malheureusement je n'ai vraiment pas beaucoup de temp en se moment, alors je n'ai rien commenté ni expliqué, si quelqu'un veut le faire a ma place se serait très volontier
(le code est juste compilé, et pas testé. Il traine peut être (surement) quelques bugs

en gros, ces fonctions servent a retenir dans une seule LocalVar de type int un total de 32 informations booléennes, idéal pour retenir les variables de dialogues par exemple, sans surcharger les ressources système.

Code PHP:

//Attribue au bit de position nPosition du groupe sIntVarName la valeur bValue
//oTrgObj : Objet cible par les variables
void SetBinInfo(object oTrgObjstring sIntVarNameint nPositionint bValue TRUE)
{
    
int iNumber;
    
int iCount 0;
    for(
iNumber nPositioniNumber 0iNumber -= 32)
        
iCount++;
    
string sStringName sIntVarName AdjustDecimal(IntToString(iCount));
    
int nVar GetLocalInt(oTrgObjsStringName);
    if(
bValuenVar nVar | (<< (32 nPosition));
    else 
nVar nVar & (4294967294 << (32 nPosition));
    
//Je ne sais pas comment faire pour mettre des variables directement en binaire (peut on sur nwscripts ?)
    //il serait quand meme plus sympa de noter 11111111111111111111111111111110 plutot que 4294967294
    
SetLocalInt(oTrgObjsStringNamenVar);
}

//Renvoie la valeur du bit de position nPosition du groupe sIntVarName
//oTrgObj : Objet cible par les variables
int GetBinInfo(object oTrgObjstring sIntVarNameint nPosition)
{
    
int iNumber;
    
int iCount 0;
    for(
iNumber nPositioniNumber 0iNumber -= 32)
        
iCount++;
    
string sStringName sIntVarName AdjustDecimal(IntToString(iCount));
    
int nVar GetLocalInt(oTrgObjsStringName);
    if((
<< (32 nPosition)) & nVar) return TRUE;
    return 
FALSE;

Il est strange ton script : à quoi servent iCount et iNumber (surtout que tels qu'ils sont créés, iCount vaut toujours 1, à moins que la nPosition soit supérieure à 32, et dans ce cas c'est l'utilisateur qui est strange... )
(A moins que tu ne veuille effectivement permettre des nPositions supérieures à 32, mais dans ce cas, ne serait-il pas plus sûr de mettre nPosition = nPosition % 32, je ne sais pas si le NWScript apprécie les décalages négatifs, à moins que tu ais testé et qu'il se comporte comme prévu ?? )

De plus j'ai un peu peur pour le bValue == FALSE (le TRUE, pas de problème) : ta fonction va effacer tout les bits de valeur inférieure....
Je proposerais plutôt : 0xFFFFFFFF - pow(2, nPosition - 1), toujours avec un &.
Mais du coup, dans un souci de compatibilité, je remplacerais la technique du bValue == TRUE par 1 << nPosition - 1 (% 32 si tu veux plus de positions possibles) toujours avec un |. Puisque ma méthode compte les bits à partir de la droite tandis que la tienne les comptait à partir de la gauche (big endian, little endian... ).

Pour le support de l'écriture directe en binaire, j'ai un doute, même s'il serait très facile de faire une fonction de conversion de chaîne vers nombre pour ça.
Par contre, le support de l'hexa, j'en suis presque sûr, il me semble que Bioware l'as même utilisé dans l'une de ses librairies.
iCount, iNumber et tout le tralala c'est pour enregistrer sur plusieurs variables int si il y a plus de 32 valeurs binaires demandées.

Citation :
Je proposerais plutôt : 0xFFFFFFFF - pow(2, nPosition - 1), toujours avec un &.
Ouaip peu être, j'ai fait la deuxième partie a l'arrache hier soir avec la fatigue qui va avec, dsl... ta solution est en effet meilleure


il me semble bien que les valeurs négatives marches, enfin on peut s'arrenger pour faire autrement, ce n'est pas très propre en effet.

Bon normalement de toutes facon je me servirais de ces fonctions dans très peu de temps, je serais donc obliger de débugger et d'arrenger, je corrigerais tout ca a cette occasion
A priori ceci devrait marcher, mais faut que je fasse des tests :
Code PHP:

//Attribue au bit de position nPosition du groupe sIntVarName la valeur bValue
//oTrgObj : Objet cible par les variables
void SetBinInfo(object oTrgObjstring sIntVarNameint nPositionint bValue TRUE)
{
    
int iNumber 0;
    for(; 
nPosition 32iNumber ++) nPosition 32;
    
    
string sStringName sIntVarName AdjustDecimal(IntToString(iNumber));
    
    
int nVar GetLocalInt(oTrgObjsStringName);
    
nVar bValue nVar pow(2nPosition 1) : nVar & (0xFFFFFFFF pow(2nPosition 1));
    
    
SetLocalInt(oTrgObjsStringNamenVar);
}


//Renvoie la valeur du bit de position nPosition du groupe sIntVarName
//oTrgObj : Objet cible par les variables
int GetBinInfo(object oTrgObjstring sIntVarNameint nPosition)
{
    
int iNumber 0;
    for(; 
nPosition 32iNumber ++) nPosition 32;
    
    
string sStringName sIntVarName AdjustDecimal(IntToString(iNumber));
    
    
int nVar GetLocalInt(oTrgObjsStringName);
    
    return 
pow(2nPosition 1) & nVar;

En tout cas ça prend moins de place que 32 local int qui ne valent que FALSE ou TRUE (0 ou 1), sérieux vous utilisez souvent d'autres valeurs vous ??
Bon testé et approuvé, surtout ne pas utiliser les scripts au-dessus, ils sont piégés (boucle infinie ) :
Code PHP:

//Renvoie la valeur du bit de position nPosition du groupe sIntVarName
//oTrgObj : Objet cible par les variables
int GetBinInfo(object oTrgObjstring sIntVarNameint nPosition);

//prend un nombre et "normalise" sa longueur
string AdjustDecimal(int nNumberint nNumberOfDecimal 3);

//Attribue au bit de position nPosition du groupe sIntVarName la valeur bValue
//oTrgObj : Objet cible par les variables
void SetBinInfo(object oTrgObjstring sIntVarNameint nPositionint bValue TRUE);

string AdjustDecimal(int nNumberint nNumberOfDecimal 3)
{
    
string sNumber IntToString(nNumber);
    
int nL GetStringLength(sNumber);

    
nL nL nNumberOfDecimal;

    if (
nL<0)
        {
        
string sR "";
        for (; 
nNumberOfDecimal;nNumberOfDecimal--)
            
sR += "0";
        return 
sR;
        }

    for (; 
nLnL--)
        
sNumber "0" sNumber;

    return 
sNumber;
}

void SetBinInfo(object oTrgObjstring sIntVarNameint nPositionint bValue TRUE)
{
    
int iNumber 0;
    for(; 
nPosition 32iNumber ++) nPosition -= 32;

    
string sStringName sIntVarName AdjustDecimal(iNumber);

    
iNumber << nPosition 1;

    
int nVar GetLocalInt(oTrgObjsStringName);
    
nVar bValue nVar iNumber nVar & ~iNumber;

    
SetLocalInt(oTrgObjsStringNamenVar);
}


int GetBinInfo(object oTrgObjstring sIntVarNameint nPosition)
{
    
int iNumber 0;
    for(; 
nPosition 32iNumber ++) nPosition -= 32;

    
string sStringName sIntVarName AdjustDecimal(iNumber);

    
iNumber << nPosition 1;

    
int nVar GetLocalInt(oTrgObjsStringName);

    return 
iNumber nVar TRUE FALSE;

Si vous voulez mon avis, c'est une sacré bonne idée d'utiliser ces fonctions, ça économisera beaucoup de place pour les variables qui en ont vraiment besoin... Après tout, 70% des variables employées sont des booléennes. (90% des local int ).
Avec cette fonction, on peut stocker 32 fois plus de booléen sur la même variable et on peut aller jusqu'à la position 31968....
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés