2009-12-01 13 views
5

Estoy convirtiendo un programa C++ a Java y me quedé completamente atrapado en el siguiente método, lo que me dejó alucinado. ¿Serías tan amable de explicar qué está haciendo este método?Conversión de patrón de bits de C++ a 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:

Mi versión de Java inicial:

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; 
} 

¿Hice lo correcto?

+0

NDataString? ¿No es ese objetivo C? –

+0

¿No desea aislar el problema un poco en lugar de publicar el código de su compañía en línea? –

+0

Por cierto, si esto te dejó sin palabras porque parece complicado y complicado, ¡bien! No lo llamaría un ejemplo de código bueno y claro. –

Respuesta

1

Toma una cadena de bytes (es decir, no de texto) y la convierte en una larga. Se basa en muchas cosas específicas de implementación, y parece estar roto: está extrayendo el bit de signo de dos lugares diferentes. Otro problema es la no reentrada innecesaria (causada por la variable estática).

+0

Si se está convirtiendo el código, es justo suponer que funciona y no está necesariamente "roto". La implementación del letrero puede ser un protocolo extraño que no estás esperando, pero eso no significa que esté roto, simplemente incómodo. – Tenner

+0

Es por eso que dije que parece estar roto, obviamente no tengo la especificación exacta para la que está escrito. –

+0

¿Podría echar un vistazo al EDIT si lo he hecho bien? Gracias. –

1
s[0] &= 0x7F; 

significa bit-y s[0] con hex 7F o en otras palabras, tira el bit de signo de la valor de byte. misma con s[len-1], por lo que:

  • toma una cadena numérica, donde el primero o el último dígito tiene un bit de signo añadido (0x30 - 0x39 == '0'-'9' y 0xB0 - 0xB9 es el mismo rango que tenga la bit 0x80.)
  • tiras que se inscriban poco, recordando como multiplicador
  • interpreta el argumento de cadena numérica usando el multiplicador para ajustar la señal de
  • rendimientos que valor

Editar:

Revisando el código me lleva a las siguientes observaciones:

  • no funciona según lo previsto, asegúrese de escribir algunas pruebas JUnit para un código nuevo para comprobar que hagan lo que espera
  • coloque los números mágicos en constantes separadas
  • use byte constantes al comparar a firmar bytes (cuestiones)
  • de los apoyos deben recibir la cosa colgando y en este caso son innecesarios
  • uso new String(byte[]) para reconstruir la cadena, no la clase de utilidad matrices.

Esto me lleva a esta versión:

// 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; 
} 

todavía tiene que prestar atención a la adición de comentarios correctos y actualizar los nombres de constantes para que estén en línea con la terminología de su documentación.

+0

¿Podría echar un vistazo al EDIT si lo he hecho bien? Gracias. –

0

Parece que está probando alguna versión extraña de signo (positiva o negativa).Si el primero o el último (pero preferiblemente el primero) personaje está entre 0xB0 y 0xB9, corte el bit más alto de cualquier carácter (por lo que es 0x30 y 0x39, los dígitos '0' hasta '0' hasta '9'). Luego devuelve el número con un signo negativo, como lo saben los humanos normales.

+0

¿Podría echar un vistazo al EDIT si lo he hecho bien? Gracias. –

Cuestiones relacionadas