Em Java, posso definir uma constante inteira em formato binário?

86

Semelhante a como você pode definir uma constante inteira em hexadecimal ou octal, posso fazer isso em binário?

Admito que essa é uma pergunta muito fácil (e estúpida). Minhas pesquisas no google estão vazias.

Aaron Fi
fonte
2
Apenas para sua informação, em praticamente todas as linguagens de programação, o idioma é escrever constantes binárias em hexadecimal, e não a string binária real.
abyx
3
Certo, mas imagino que seja porque hex é a coisa mais próxima disponível, não porque há algo errado com binário. Em linguagens que usei que oferecem suporte a literais binários, não acho que a convenção seja ignorar esse recurso.
Ken
Ano de 2017: a resposta aceita deve ser a fornecida por Russ. Consulte: stackoverflow.com/a/1692932/716079
Lourenço

Respostas:

66

Portanto, com o lançamento do Java SE 7, a notação binária vem padrão fora da caixa. A sintaxe é bastante direta e óbvia se você tiver um entendimento decente de binário:

byte fourTimesThree = 0b1100;
byte data = 0b0000110011;
short number = 0b111111111111111; 
int overflow = 0b10101010101010101010101010101011;
long bow = 0b101010101010101010101010101010111L;

E especificamente no ponto de declarar variáveis ​​de nível de classe como binários, não há absolutamente nenhum problema ao inicializar uma variável estática usando notação binária:

public static final int thingy = 0b0101;

Apenas tome cuidado para não sobrecarregar os números com muitos dados, ou você receberá um erro do compilador:

byte data = 0b1100110011; // Type mismatch: cannot convert from int to byte

Agora, se você realmente quiser ficar mais sofisticado, pode combinar aquele outro novo recurso interessante do Java 7 conhecido como literais numéricos com sublinhados. Dê uma olhada nestes exemplos sofisticados de notação binária com sublinhados literais:

int overflow = 0b1010_1010_1010_1010_1010_1010_1010_1011;
long bow = 0b1__01010101__01010101__01010101__01010111L;

Agora, isso não é bonito e limpo, para não mencionar altamente legível?

Retirei esses trechos de código de um pequeno artigo que escrevi sobre o tópico no TheServerSide. Sinta-se à vontade para conferir para mais detalhes:

Java 7 e notação binária: como dominar o exame OCP Java Programmer (OCPJP)

Cameron McKenzie
fonte
3
Por que seu byte data = 0b0000110011; tem 10 bits? Sou novo em programação, mas acho que deve ser semelhante a 0b00110011 para caber em 8 bits de tipo de dados de byte.
Mike
1
Para qualquer um que esteja se perguntando o mesmo que Mike, é porque o compilador o converte no número que representa - você pode ter dezenas de zeros à esquerda e eles não afetarão o valor real. O processo de compilação é essencialmente o mesmo como se você tivesse escrito um decimal lá.
Luke Briggs
1
por definição, o byte de tipo primitivo pode armazenar 256 números entre -128 a 127 (-128 a -1 e 0 a 127). Mas como representar -128 usando um literal binário. por exemplo, byte b = -0b1111111; denota -127, mas e quanto a -128?
nirmalsingh
152

Em Java 7:

int i = 0b10101010;

Não há literais binários em versões anteriores do Java (veja outras respostas para alternativas).

Russ Hayward
fonte
33
Também gostaria de salientar que pode haver _caracteres para tornar a sequência mais legível: int i = 0b1010_1010_0011;
user12345613
@Russ O que 0b significa aqui? Como esse recurso é chamado no Java 7?
Geek
1
0b significa binário. O recurso é chamado de literais binários: docs.oracle.com/javase/7/docs/technotes/guides/language/…
Russ Hayward
1
Adoro esta nova representação de dados binários. A representação String seria muito difícil de ler. Observe a diferença entre a resposta aceita e a de "@ user12345613". 1 para ele.
Marcello de Sales
54

Não há literais binários em Java, mas suponho que você possa fazer isso (embora eu não entenda o ponto):

int a = Integer.parseInt("10101010", 2);
Ed S.
fonte
1
Entre outros usos, o padrão pontilhado para rasterização de linha e polígono é especificado como um inteiro em várias bibliotecas gráficas populares. Usar parseInt ou parseShort permite que o desenvolvedor visualize facilmente o padrão.
charstar
5
Desde Java 7, a resposta de Russ Hayward é a resposta correta. Antes do Java 7, você pode usar uma ferramenta online ou sua calculadora favorita para converter o binário em uma das notações reconhecidas pelas versões antigas do Java (octal, decimal ou hexadecimal). Se outra raiz for usada, um comentário descritivo contendo a representação binária pode ser colocado na declaração para esclarecer o valor para os leitores.
Jason C de
Esta é uma solução bastante suja, não é? Você está pegando 16 bytes para representar 1 byte (sem contar o segundo argumento e a conversão). Claro, a menos que o compilador otimize isso, o que eu duvido.
Tomáš Zato - Reintegração de Monica
@ TomášZato: Sim, é, mas que solução você sugeriria, visto que a linguagem não suportava literais binários quando escrevi esta resposta? Russ Hayward deveria ter a resposta aceita agora.
Ed S.
Eu sugeriria abrir mão do conforto e usar números inteiros. Na própria definição da variável, está tudo bem, mas essa resposta pode motivar os usuários a usar essa abordagem para loops, etc. E, geralmente, acho que o programador deve tentar abrir mão de seu próprio conforto por algum desempenho.
Tomáš Zato - Reintegrar Monica em
18

A resposta de Ed Swangren

public final static long mask12 = 
  Long.parseLong("00000000000000000000100000000000", 2);

funciona bem. Usei em longvez de inte adicionei os modificadores para esclarecer o possível uso como máscara de bits. Existem, porém, dois inconvenientes com essa abordagem.

  1. A digitação direta de todos aqueles zeros está sujeita a erros
  2. O resultado não está disponível em formato decimal ou hexadecimal no momento do desenvolvimento

Posso sugerir uma abordagem alternativa

public final static long mask12 = 1L << 12;

Essa expressão torna óbvio que o 12º bit é 1 (a contagem começa em 0, da direita para a esquerda); e quando você passa o cursor do mouse, a dica de ferramenta

long YourClassName.mask12 = 4096 [0x1000]

aparece no Eclipse. Você pode definir constantes mais complicadas como:

public final static long maskForSomething = mask12 | mask3 | mask0;

ou explicitamente

public final static long maskForSomething = (1L<<12)|(1L<<3)|(1L<<0);

O valor da variável maskForSomethingainda estará disponível no Eclipse no momento do desenvolvimento.

chgman
fonte
Solução brilhante! (máscara longa estática final pública 12 = 1L << 12;)
Jyro117
17

Usando constantes binárias para mascarar

Declare constantes:

public static final int FLAG_A = 1 << 0;
public static final int FLAG_B = 1 << 1;
public static final int FLAG_C = 1 << 2;
public static final int FLAG_D = 1 << 3;

e usá-los

if( (value & ( FLAG_B | FLAG_D )) != 0){
    // value has set FLAG_B and FLAG_D
}
Pawelzieba
fonte
12

Procure por "sintaxe de literais Java" no Google e você encontrará algumas entradas.

Há uma sintaxe octal (prefixe seu número com 0), sintaxe decimal e sintaxe hexadecimal com um prefixo "0x". Mas nenhuma sintaxe para notação binária.

Alguns exemplos:

int i = 0xcafe ; // hexadecimal case
int j = 045 ;    // octal case
int l = 42 ;     // decimal case
Pierre
fonte
1
Isso não responde à pergunta.
Michael McQuade
Ano de 2017: Felizmente, há notação para representação binária. Começa com "0b". Exemplo: byte b = 0b01000001(para uma melhor leitura byte b = 0b0100_0001).
Lourenço de
2

Se você quiser mexer com muitos binários, pode definir algumas constantes:

public static final int BIT_0 = 0x00000001;
public static final int BIT_1 = 0x00000002;

etc.

ou

public static final int B_00000001 = 0x00000001;
public static final int B_00000010 = 0x00000002;
public static final int B_00000100 = 0x00000004;
Anthony Hayward
fonte
0

Resposta um pouco mais estranha:

public class Main {

    public static void main(String[] args) {
        byte b = Byte.parseByte("10", 2);
        Byte bb = new Byte(b);
        System.out.println("bb should be 2, value is \"" + bb.intValue() + "\"" );
    }

}

cuja saída [java] bb deve ser 2, o valor é "2"

NSherwin
fonte