在Java中,我可以定义二进制格式的整数常量吗?


85

与您可以用十六进制或八进制定义整数常量的方式类似,我可以用二进制格式来做到这一点吗?

我承认这是一个非常简单(愚蠢)的问题。我的Google搜索即将显示为空。


2
仅供参考,几乎在每种编程语言中,习惯用法都是以十六进制编写二进制常量,而不是实际的二进制字符串。
abyx

3
是的,但是我想那是因为十六进制是可用的最接近的东西,而不是因为二进制有问题。在我使用的支持二进制文字的语言中,我不认为约定会忽略此功能。


2017年:接受的答案必须是拉斯提供的答案。请参阅:stackoverflow.com/a/1692932/716079
Lourenco,

Answers:


65

因此,随着Java SE 7的发布,二进制表示法开箱即用。如果您对二进制有相当的了解,那么语法非常简单明了:

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

特别是在将类级别变量声明为二进制的方面,使用二进制表示法初始化静态变量绝对没有问题:

public static final int thingy = 0b0101;

请注意不要让数字溢出太多数据,否则您将得到编译器错误:

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

现在,如果您真的想花哨的话,可以将Java 7中的其他新功能(称为数字文字和下划线)结合起来。看一下这些带有文字下划线的奇特示例:

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

现在不是那么干净整洁,更不用说高度可读了吗?

我从TheServerSide上一篇有关该主题的小文章中提取了这些代码片段。随意查看更多详细信息:

Java 7和二进制表示法:掌握OCP Java程序员(OCPJP)考试


3
为什么您的字节数据= 0b0000110011; 有10位?我是编程新手,但我认为它应该看起来像0b00110011以适合8位字节数据类型。
2014年

1
对于任何想知道与Mike相同的人,这是因为编译器将其转换为它代表的数字-您可能会有数十个前导零,并且它们不会影响实际值。编译过程本质上与在其中编写小数点的过程相同。
卢克·布里格斯

1
根据定义,原始类型字节可以存储-128至127(-128至-1和0至127)之间的256个数字。但是如何使用二进制文字表示-128。例如字节b = -0b1111111; 表示-127但-128呢?
nirmalsingh

152

在Java 7中:

int i = 0b10101010;

Java的较早版本中没有二进制文字(请参阅其他答案以获取替代方法)。


33
我还想指出,可以有一些_字符使序列更易读: int i = 0b1010_1010_0011;
user12345613 2012年

@Russ 0b在这里表示什么?Java 7中将此功能称为什么?
怪胎

1
0b表示二进制。该功能称为二进制文字:docs.oracle.com/javase/7/docs/technotes/guides/language/…–
Russ Hayward,

1
喜欢这种二进制数据的新表示形式。字符串表示将很难阅读。查看所接受答案与“ @ user12345613”中答案的区别。为他+1。
Marcello de Sales

54

Java中没有二进制文字,但是我想您可以做到这一点(尽管我看不到重点):

int a = Integer.parseInt("10101010", 2);

1
除其他用途外,在一些流行的图形库中,用于线和面栅格化的点画图案还指定为整数。使用parseInt或parseShort可使开发人员轻松可视化模式。
charstar

5
从Java 7开始,Russ Hayward的答案是正确的答案。在Java 7之前,您可以使用在线工具或您喜欢的计算器将二进制文件转换为旧Java版本(八进制,十进制或十六进制)可以识别的符号之一。如果使用另一个基数,则可以在声明中放置包含二进制表示形式的描述性注释,以为读者澄清其值。
詹森·C

这是一个相当肮脏的解决方案,不是吗?您只用16个字节代表1个字节(不计算第二个参数和转换)。当然,除非编译器对此进行优化,否则我对此表示怀疑。
托马什Zato -恢复莫妮卡

@TomášZato:是的,但是,鉴于我编写此答案时该语言不支持二进制文字,您会提出什么解决方案?Russ Hayward现在应该已经接受了答案。
Ed S.

我建议放弃舒适性并使用整数。就变量定义本身而言,这是可以的,但是这个答案可能会促使用户将这种方法用于循环等。通常,我认为程序员应该为某些性能放弃自己的舒适感。
托马什Zato -恢复莫妮卡

18

Ed Swangren的回答

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

工作正常。我使用long而不是,int并添加了修饰符以阐明可能的用法作为位掩码。但是,这种方法有两个不便之处。

  1. 直接输入所有这些零容易出错
  2. 开发时结果不可用十进制或十六进制格式

我可以建议替代方法

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

该表达式使第12位明显为1(计数从0开始,从右到左)。当您将鼠标悬停在

long YourClassName.mask12 = 4096 [0x1000]

出现在Eclipse中。您可以定义更复杂的常量,例如:

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

或明确地

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

maskForSomething在开发时,变量的值仍将在Eclipse中可用。


出色的解决方案!(公共最终静态长掩码12 = 1L << 12;)
Jyro117

16

使用二进制常量进行屏蔽

声明常量:

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;

并使用它们

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

12

在Google上搜索“ Java文字语法”,您会得到一些输入。

有八进制语法(以0前缀数字),十进制语法和带有“ 0x”前缀的十六进制语法。但是没有二进制表示法的语法。

一些例子:

int i = 0xcafe ; // hexadecimal case
int j = 045 ;    // octal case
int l = 42 ;     // decimal case

1
这不能回答问题。
Michael McQuade

2017年:幸运的是,这里使用了二进制表示法。它以“ 0b”开头。示例:( byte b = 0b01000001为了更好的读取性byte b = 0b0100_0001)。
Lourenco

2

如果您想弄乱大量二进制文件,可以定义一些常量:

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

等等

要么

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

0

稍微尴尬的答案:

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

}

输出[java] bb应该为2,值为“ 2”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.