En Java, ¿puedo definir una constante entera en formato binario?

85

Similar a cómo se puede definir una constante entera en hexadecimal u octal, ¿puedo hacerlo en binario?

Admito que esta es una pregunta realmente fácil (y estúpida). Mis búsquedas de Google están vacías.

Aaron Fi
fuente
2
Para su información, en casi todos los lenguajes de programación, el idioma es escribir constantes binarias en hexadecimal, y no la cadena binaria real.
abyx
3
Bien, pero me imagino que es porque hexadecimal es lo más parecido disponible, no porque haya algo mal con el binario. En los lenguajes que he usado que admiten literales binarios, no creo que la convención sea ignorar esta característica.
Ken
Año 2017: la respuesta aceptada debe ser la proporcionada por Russ. Ver: stackoverflow.com/a/1692932/716079
Lourenco

Respuestas:

65

Entonces, con el lanzamiento de Java SE 7, la notación binaria viene de serie. La sintaxis es bastante sencilla y obvia si tiene una comprensión decente de binario:

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

Y específicamente en el punto de declarar variables de nivel de clase como binarios, tampoco hay absolutamente ningún problema al inicializar una variable estática usando notación binaria:

public static final int thingy = 0b0101;

Solo tenga cuidado de no desbordar los números con demasiados datos, o obtendrá un error del compilador:

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

Ahora, si realmente quiere ser elegante, puede combinar esa otra característica nueva y ordenada en Java 7 conocida como literales numéricos con guiones bajos. Eche un vistazo a estos elegantes ejemplos de notación binaria con guiones bajos literales:

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

¿No es eso agradable y limpio, sin mencionar que es muy legible?

Saqué estos fragmentos de código de un pequeño artículo que escribí sobre el tema en TheServerSide. No dude en consultarlo para obtener más detalles:

Java 7 y notación binaria: dominio del examen OCP Java Programmer (OCPJP)

Cameron McKenzie
fuente
3
¿Por qué su byte data = 0b0000110011; tiene 10 bits? Soy nuevo en programación, pero creo que debería parecerse a 0b00110011 para adaptarse a 8 bits de tipo de datos de bytes.
Mike
1
Para cualquiera que se pregunte lo mismo que Mike, es porque el compilador lo convierte en el número que representa; podría tener decenas de ceros iniciales y no afectarán el valor real. El proceso de compilación es esencialmente el mismo que si hubiera escrito un decimal allí.
Luke Briggs
1
por definición, el byte de tipo primitivo puede almacenar 256 números entre -128 y 127 (-128 a -1 y 0 a 127). Pero cómo representar -128 usando un literal binario. por ejemplo, byte b = -0b1111111; denota -127 pero ¿qué pasa con -128?
nirmalsingh
152

En Java 7:

int i = 0b10101010;

No hay literales binarios en versiones anteriores de Java (consulte otras respuestas para conocer las alternativas).

Russ Hayward
fuente
33
También me gustaría señalar que puede haber _caracteres para hacer que la secuencia sea más legible: int i = 0b1010_1010_0011;
user12345613
@Russ ¿Qué significa 0b aquí? ¿Cómo se llama esta función en Java 7?
Geek
1
0b significa binario. La función se llama literales binarios: docs.oracle.com/javase/7/docs/technotes/guides/language/…
Russ Hayward
1
Amo esta nueva representación de datos binarios. La representación String sería muy difícil de leer. Mire la diferencia entre la respuesta aceptada y la de "@ user12345613". +1 para él.
Marcello de Sales
54

No hay literales binarios en Java, pero supongo que podrías hacer esto (aunque no veo el punto):

int a = Integer.parseInt("10101010", 2);
Ed S.
fuente
1
Entre otros usos, el patrón de punteado para la rasterización de líneas y polígonos se especifica como un número entero en varias bibliotecas gráficas populares. El uso de parseInt o parseShort permite al desarrollador visualizar fácilmente el patrón.
charstar
5
Desde Java 7, la respuesta de Russ Hayward es la respuesta correcta. Antes de Java 7, puede usar una herramienta en línea o su calculadora favorita para convertir binario a una de las notaciones reconocidas por las versiones antiguas de Java (octal, decimal o hexadecimal). Si se usa otra base, se puede colocar un comentario descriptivo que contenga la representación binaria en la declaración para aclarar el valor para los lectores.
Jason C
Esta es una solución bastante sucia, ¿no? Solo está tomando 16 bytes para representar 1 byte (sin contar el segundo argumento y la conversión). Por supuesto, a menos que el compilador optimice esto, lo cual dudo.
Tomáš Zato - Reincorporación a Monica
@ TomášZato: Sí, lo es, pero ¿qué solución sugeriría dado que el lenguaje no admitía literales binarios cuando escribí esta respuesta? Russ Hayward debería tener la respuesta aceptada ahora.
Ed S.
Sugeriría renunciar a la comodidad y usar números enteros. En la definición de variable en sí, está bien, pero esta respuesta podría motivar a los usuarios a usar este enfoque para bucles, etc. Y, en general, creo que el programador debería intentar renunciar a su propia comodidad por algo de rendimiento.
Tomáš Zato - Reincorporación a Monica
18

La respuesta de Ed Swangren

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

funciona bien. Usé en longlugar de inty agregué los modificadores para aclarar el posible uso como una máscara de bits. Sin embargo, existen dos inconvenientes con este enfoque.

  1. La escritura directa de todos esos ceros es propensa a errores
  2. El resultado no está disponible en formato decimal o hexadecimal en el momento del desarrollo

Puedo sugerir un enfoque alternativo

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

Esta expresión hace obvio que el 12º bit es 1 (la cuenta comienza desde 0, de derecha a izquierda); y cuando pasa el cursor del mouse, la información sobre herramientas

long YourClassName.mask12 = 4096 [0x1000]

aparece en Eclipse. Puede definir constantes más complicadas como:

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

o explícitamente

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

El valor de la variable maskForSomethingseguirá estando disponible en Eclipse durante el desarrollo.

chgman
fuente
¡Solución brillante! (public final static long mask12 = 1L << 12;)
Jyro117
16

Usar constantes binarias para enmascarar

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

y usarlos

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

Busque "sintaxis de literales de Java" en Google y obtendrá algunas entradas.

Hay una sintaxis octal (prefija su número con 0), sintaxis decimal y sintaxis hexadecimal con un prefijo "0x". Pero no hay sintaxis para notación binaria.

Algunos ejemplos:

int i = 0xcafe ; // hexadecimal case
int j = 045 ;    // octal case
int l = 42 ;     // decimal case
Pierre
fuente
1
Esto no responde a la pregunta.
Michael McQuade
Año 2017: Afortunadamente, existe una notación para la representación binaria. Comienza con "0b". Ejemplo: byte b = 0b01000001(para una mejor lectura byte b = 0b0100_0001).
Lourenco
2

Si quieres jugar con muchos binarios, puedes definir algunas constantes:

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

etc.

o

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

Respuesta un poco más incómoda:

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() + "\"" );
    }

}

cuya salida [java] bb debe ser 2, el valor es "2"

NSherwin
fuente