Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

514
Visualizações
How can I safely use a Java byte as an unsigned char?

I am porting some C code that uses a lot of bit manipulation into Java. The C code operates under the assumption that int is 32 bits wide and char is 8 bits wide. There are assertions in it that check whether those assumptions are valid.

I have already come to terms with the fact that I'll have to use long in place of unsigned int. But can I safely use byte as a replacement for unsigned char?

They merely represent bytes, but I have already run into this bizarre incident: (data is an unsigned char * in C and a byte[] in 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;

You would think a left shift operation is safe. But due strange unary promotion rules in Java, a and b are not going to be the same if some of the bytes in data are "negative" (b gives the correct result).

What other "gotchas" should I be aware of? I really don't want to use short here.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

You can safely use a byte to represent a value between 0 and 255 if you make sure to bitwise-AND its value with 255 (or 0xFF) before using it in computations. This promotes it to an int, and ensures the promoted value is between 0 and 255.

Otherwise, integer promotion would result in an int value between -128 and 127, using sign extension. -127 as a byte (hex 0x81) would become -127 as an int (hex 0xFFFFFF81).

So you can do this:

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

Note that the first & 255 is unnecessary here, since a later step masks off the extra bits anyway (& 0xffffffff). But it's probably simplest to just always include it.

over 4 years ago · Santiago Trujillo Relatório

0

...can I safely use byte as a replacement for unsigned char ?

As you've discovered, not really... No.

According to the Oracle Java documentation , byte is a signed integer type, and although it has 256 distinct values (because of the explicit range specification "Has a minimum value of -128 and a maximum value of 127 (inclusive)" of documentation) there are values that a C unsigned char can store, that a Java byte cannot (and vice versa).

That explains the problem you've experienced. However, the scope of the problem has not been fully demonstrated in its 8-bit byte implementation.


What other "pitfalls" should I be aware of?

While a byte in Java is required to support only values between (and inclusive of) -128 and 127, Cs unsigned char has a maximum value ( UCHAR_MAX ) that depends on the number of bits used to represent it ( CHAR_BIT ; at least 8). So when CHAR_BIT is greater than 8, there will be additional values beyond 255 that can be stored in unsigned char .


In short, in the Java world, a byte really should be called an octet (a group of eight bits), whereas in C a byte ( char , signed char , unsigned char ) is a group of at least (possibly more than) eight bits .

No. They are not equivalent. I also don't think you'll find an equivalent type in Java; they are all rather fixed-width . However, you could use byte in Java as an equivalent for int8_t in C (except that int8_t is not required to exist in C unless CHAR_BIT == 8 ).


As for the pitfalls, there are also some in your C code. Assuming data[0] is an unsigned char , data[0] << 24 is undefined behavior on any system for which INT_MAX == 32767 .

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda