Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

522
Vistas
¿Cómo puedo usar de manera segura un byte de Java como un carácter sin firmar?

Estoy transfiriendo un código C que usa mucha manipulación de bits a Java. El código C opera bajo el supuesto de que int tiene 32 bits de ancho y char tiene 8 bits de ancho. Hay afirmaciones en él que verifican si esas suposiciones son válidas.

Ya he llegado a un acuerdo con el hecho de que tendré que usar long en lugar de unsigned int . Pero, ¿puedo usar byte de manera segura como reemplazo de unsigned char ?

Simplemente representan bytes, pero ya me encontré con este extraño incidente: ( data son un unsigned char * en C y un byte[] en Java):

 /* C */ uInt32 c = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; /* Java */ long a = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]) & 0xffffffff; long b = ((data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff) & 0xffffffff;

Uno pensaría que una operación de cambio a la izquierda es segura. Pero debido a las extrañas reglas de promoción unaria en Java, a y b no van a ser lo mismo si algunos de los bytes en data son "negativos" ( b da el resultado correcto).

¿Qué otros "trampas" debo tener en cuenta? Realmente no quiero usar short aquí.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Puede usar un byte de forma segura para representar un valor entre 0 y 255 si se asegura de hacer AND bit a bit su valor con 255 (o 0xFF) antes de usarlo en los cálculos. Esto lo promociona a un int y garantiza que el valor promocionado esté entre 0 y 255.

De lo contrario, la promoción de enteros daría como resultado un valor int entre -128 y 127, utilizando la extensión de signo. -127 como byte (0x81 hexadecimal) se convertiría en -127 como int (0xFFFFFF81 hexadecimal).

Así que puedes hacer esto:

 long a = (((data[0] & 255) << 24) | ((data[1] & 255) << 16) | ((data[2] & 255) << 8) | (data[3] & 255)) & 0xffffffff;

Tenga en cuenta que el primer & 255 no es necesario aquí, ya que un paso posterior enmascara los bits adicionales de todos modos ( & 0xffffffff ). Pero probablemente sea más simple incluirlo siempre.

over 4 years ago · Santiago Trujillo Denunciar

0

... ¿puedo usar byte de forma segura como reemplazo de unsigned char ?

Como has descubierto, en realidad no... No.

De acuerdo con la documentación de Oracle Java , byte es un tipo entero con signo, y aunque tiene 256 valores distintos (debido a la especificación de rango explícita "Tiene un valor mínimo de -128 y un valor máximo de 127 (inclusive)" de la documentación) hay valores que un unsigned char de C puede almacenar, que un byte de Java no puede (y viceversa).

Eso explica el problema que has experimentado. Sin embargo, el alcance del problema no se ha demostrado completamente en su implementación de bytes de 8 bits.


¿Qué otros "trampas" debo tener en cuenta?

Si bien se requiere que un byte en Java admita solo valores entre (e inclusive) -128 y 127, Cs unsigned char tiene un valor máximo ( UCHAR_MAX ) que depende de la cantidad de bits utilizados para representarlo ( CHAR_BIT ; al menos 8) . Entonces, cuando CHAR_BIT es mayor que 8, habrá valores adicionales más allá de 255 que se pueden almacenar unsigned char .


En resumen, en el mundo de Java, un byte realmente debería llamarse octet (un grupo de ocho bits), mientras que en C un byte ( char , signed char , unsigned char ) es un grupo de al menos (posiblemente más de) ocho bits .

No. No son equivalentes. Tampoco creo que encuentre un tipo equivalente en Java; todos son más bien de ancho fijo . Sin embargo, podría usar byte en Java como un equivalente para int8_t en C (excepto que no se requiere que int8_t exista en C a menos que CHAR_BIT == 8 ).


En cuanto a las trampas, también hay algunas en su código C. Suponiendo data[0] es un unsigned char , data[0] << 24 es un comportamiento indefinido en cualquier sistema para el que INT_MAX == 32767 .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda