6
votes

Bit Shift quand il n'y a pas de ... Opérateur de changement de bits

Je dois mettre en œuvre une somme de contrôle (CRC16 CCITT) pour vérifier le contenu d'un fichier. La somme de contrôle est plutôt simple à mettre en œuvre dans C ou Java grâce à des opérateurs > et les nombreux exemples disponibles sur le net.

La chose est ... mon calcul de checksum doit être mis en œuvre dans VBScript. P>

Mon expérience avec cette langue est presque nulle mais de ma compréhension, il n'y a plus rien à faire pour passer le morceau VBScript. Par conséquent, je compte sur multiplications et divisions par deux. Strong> ça marche bien sauf avec valeurs négatives forts>. P>

J'ai couru peu de tests et je crois que VBScript gère sa 16 bits nombres entiers avec le complément de deux. P>

Q1: strong> Quelqu'un peut-il me confirmer cela (deux deux complément à VBScript)? Je n'ai trouvé aucune information précise du site Web MSDN. P>

Q2: strong> est-il possible de faire un changement de bit (à droite et à gauche) avec des opérations mathématiques simples lorsque le nombre négatif est codé avec le complément de deux? p>

. P>

Merci beaucoup, j'aimerais vraiment éviter un kilométrage comme traiter avec des entiers comme des tableaux de "1" et de "0 'ou de l'appeler Application Java / C de VBScript. P>

EDIT STRY> Merci pour l'aide, trouvez ci-dessous mon implémentation d'un décalage à droite dans VBScript: P>

Function rightShift(value,bits)
    Dim res

    res = 65535 AND value

    If value>=0 Then
       res = res \ (2^bits)
    Else If value=-1 Then
             res = rightShift(res + 32768, bits - 1)
         Else
             res = rightShift(value \ 2 + 32768, bits - 1)
         End If
    End If

    rightShift = res AND 65535
End Function 


1 commentaires

Merci beaucoup d'avoir remis votre code! J'avais besoin de la même chose, à l'exception de 32 bits, qui était facile à voir avec votre code. :) Je suis en train de mettre en œuvre CRC32. :)


3 Réponses :


5
votes

En deux-complément arithmétique, le seul impact que les valeurs négatives se produisent lors de la division par 2 pour passer à droite: le changement de droite prévu aura lieu, mais il introduira également un nouveau 1 bit dans le bit le plus significatif (MSB ) Positionner à "Garder la valeur négative" - ​​à moins que la valeur d'origine ne soit -1, auquel cas tous les bits deviennent 0. SO afin de le corriger, essayez le pseudocode suivant:

rightshift(x) {
    if x >= 0 return x / 2;
    if x < -1 return x / 2 - MINVAL;    # Strip out sign bit
    # x must be -1, i.e. "all bits on"
    return x - MINVAL;
}


1 commentaires

C'est parfait ! Merci pour cette explication! Cela fonctionne comme un charme maintenant.



0
votes

Ce n'est pas une réponse, mais un commentaire. La réponse donnée par @j_random_hacker a travaillé pour moi. Mais dans les langues qui effectuent des divisions entières telles que c # (en supposant que vous ne puissiez pas utiliser l'opérateur de changement de vitesse intégré pour une raison quelconque), il faut arrondir lorsque X n'est même pas.

static int MINVAL = (int) -0x80000000;
    static int ShiftRight(int n,int bits)
    {
        //if (n >= 0) return n / (int)Math.Pow(2, bits);
        //double temp = n / Math.Pow(2, bits);
        //int r  = (int) Math.Floor(temp);
        //return r;
        if (n >= 0) return n / 2;
        if (n < -1) return (int)Math.Round(n / (double)2, MidpointRounding.AwayFromZero) - MINVAL;//+ (n%2==0?0:-1);    // Strip out sign bit
        // x must be -1, i.e. "all bits on"
        return n - MINVAL;
    }


0 commentaires

-1
votes

C'est très lent, essayez ceci. Les œuvres suivantes pour les valeurs> = 0 mais la volonté Lancer un indice de tableau hors des limites pour BitShifts> 14 bits et le code est le suivant: xxx pré>

multipliez par le nombre de bits à décaler pour le décalage de gauche. Divisez pour le changement de droite. Ce tableau fonctionne pour des entiers de 16 bits. P>

pour les entiers 32 bits Le tableau évitera hors des limites Indice pour les bitShifts> 30 et est le suivant: P>

dim ShiftArray
ShiftArray = Array(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,   
2048,4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288,
1048576, 2097152, 4194304, 8388608, 16777216, 33554432,
67108864, 134217728, 268435456,  536870912, 1073741824)


0 commentaires