2009-12-01 6 views
5

Je suis en train de convertir un programme C++ en Java et je me suis complètement bloqué dans la méthode suivante qui m'a bouleversé l'esprit. Auriez-vous l'amabilité d'expliquer ce que fait cette méthode?Conversion du modèle de bits C++ en Java

long TSBCA::GetSignedValue(const NDataString &value) 
    { 
     static NDataString s;  
     s = value; 

     long multiplier(1); 
     size_t len(s.Len()); 
     if (len != 0) 
     { 
      if (s[0] >= (char)0xB0 && s[0] <= (char)0xB9) 
      { 
      s[0] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else if (s[len - 1] >= (char)0xB0 && s[len - 1] <= (char)0xB9) 
      { 
      s[len - 1] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else 
      multiplier = 1; 
     } 
     else 
      multiplier = 1; 
     return s.ToLong() * multiplier; 
    } 

EDIT:

Ma première version Java:

private long getSignedValue(final String value){ 

     byte[] bytes = value.getBytes(); 
     int length = bytes.length; 
     long multiplier = 1L; 

     if (bytes.length > 0){ 
      if (bytes[0] >= (char)0xB0 && bytes[0] <= (char)0xB9){ 


      bytes[0] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else if (bytes[length - 1] >= (char)0xB0 && bytes[length - 1] <= (char)0xB9) 
      { 
       bytes[length - 1] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else 
      multiplier = 1; 
     } 
     else 
      multiplier = 1; 
     return Long.parseLong(Arrays.toString(bytes))* multiplier; 
} 

Est-ce que je le fais pas?

+0

NDataString? N'est-ce pas l'objectif C? –

+0

Vous ne voulez pas isoler un peu le problème au lieu d'afficher le code de votre entreprise en ligne? –

+0

BTW, si cela a soufflé votre esprit parce qu'il semble compliqué et alambiqué, bon! Je ne dirais pas que c'est un bon exemple de code clair. –

Répondre

1

Il faut une chaîne d'octets (c'est-à-dire pas de texte) et de convertir en long. Il repose sur de nombreuses choses spécifiques à l'implémentation et semble cassé: il extrait le bit de signe de deux endroits différents. Un autre problème est la non-réentrance inutile (causée par la variable statique).

+0

S'il s'agit d'un code converti, il est juste de supposer que cela fonctionne et n'est pas nécessairement "cassé". L'implémentation du signe peut être un protocole étrange auquel vous ne vous attendez pas, mais cela ne veut pas dire qu'il est brisé, juste maladroit. – Tenner

+0

C'est pourquoi j'ai dit qu'il semble cassé, évidemment je n'ai pas la spécification exacte à laquelle il est écrit. –

+0

Pourriez-vous s'il vous plaît jeter un oeil à l'EDIT si j'ai bien fait? Je vous remercie. –

1
s[0] &= 0x7F; 

signifie bit et s[0] avec six pans 7F ou en d'autres termes, la bande le bit de signe de la valeur d'octet. même avec s[len-1], il:

  • prend une chaîne numérique, où le premier ou le dernier chiffre a un bit de signe ajouté (0x30 - 0x39 de == '0'-'9' et 0xB0 - 0xB9 est la même gamme avec la 0x80 bit.)
  • des bandes que bit de signe, en rappelant que ce multiplicateur
  • interprète l'argument de la chaîne numérique en utilisant le multiplicateur pour régler le signe
  • rendements Valeur

Modifier:

Revoir votre code me conduit aux remarques suivantes:

  • ne fonctionne pas comme prévu, assurez-vous d'écrire quelques tests JUnit pour le nouveau code pour vérifier qu'ils font ce que vous attendez
  • placez les nombres magiques dans des constantes séparées
  • utilisez byte constantes lors de la comparaison à octets (Signez numéros)
  • le d'autre ballants devrait obtenir des accolades et dans ce cas sont inutiles
  • utilisation new String(byte[]) pour reconstruire la chaîne, et non pas la classe utilitaire tableaux.

Cela me conduit à cette version:

// Bit Pattern: 0111 1111 
private static final int BYTE_7F = 0x7F; 

// '0' with sign bit set 
private static final byte BYTE_NEGATIVE_0 = (byte) 0xB0; 

// '9' with sign bit set 
private static final byte BYTE_NEGATIVE_9 = (byte) 0xB9; 


private long getSignedValue(String value) { 

    byte[] bytes = value.getBytes(); 
    final int length = bytes.length; 
    long multiplier = 1; 

    if (0 < length) { 
     if (bytes[0] >= BYTE_NEGATIVE_0 && bytes[0] <= BYTE_NEGATIVE_9) { 

      bytes[0] &= BYTE_7F; 
      multiplier = -1; 

     } else if (bytes[length - 1] >= BYTE_NEGATIVE_0 && bytes[length - 1] <= BYTE_NEGATIVE_9) { 
      bytes[length - 1] &= BYTE_7F; 
      multiplier = -1; 
     } 
    } 

    return Long.parseLong(new String(bytes)) * multiplier; 
} 

Il vous reste à faire attention à l'ajout de commentaires corriger et mettre à jour les noms constants pour les mettre en conformité avec la terminologie de votre documentation.

+0

Pourriez-vous s'il vous plaît jeter un oeil à l'EDIT si j'ai bien fait? Je vous remercie. –

0

On dirait qu'il teste une version étrange du signe (positif ou négatif).Si le premier ou le dernier caractère (mais préférablement le premier) est compris entre 0xB0 et 0xB9, alors hachez le bit le plus fort de n'importe quel caractère (le faisant entre 0x30 et 0x39, les chiffres '0' à '9'). Puis renvoyez le nombre avec un signe négatif comme les humains normaux le savent.

+0

Pourriez-vous s'il vous plaît jeter un oeil à l'EDIT si j'ai bien fait? Je vous remercie. –