Java 二进制文字:"Long number too large."
Java binary literal: "Long number too large."
所以我正在写一个国际象棋引擎。我对每个棋子的移动都有单独的方法,return 一个大小为 2 的长数组,包括移动掩码和攻击掩码的长表示。问题是,由于某种原因,当 piece move 方法生成一个 long 且索引设置为 MSB 时,我的其他方法与此输入不一致。这是以骑士为例的代码。
public long[] calculateKnightMoves(int square, long ownSideBitboard,long enemySide, long allPieces){
/*
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 2, 0, 3, 0, 0]
[0, 0, 1, 0, 0, 0, 4, 0]
[0, 0, 0, 0, x, 0, 0, 0]
[0, 0, 8, 0, 0, 0, 5, 0]
[0, 0, 0, 7, 0, 6, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
*/
//8 possible moves for a knight, depending on which file you are on. Cannot move into a discovered check for your own king.
long knightLocation = 1L<<square;
//checking to see if knight is on a or b file
long spot1Clip = Lookups.fileTables[0] & Lookups.fileTables[1] & knightLocation;
//checking to see if knight is on a file
long spot2Clip = Lookups.fileTables[0] & knightLocation;
//checking to see if knight is on h file
long spot3Clip = Lookups.fileTables[Lookups.fileTables.length-2] & knightLocation;
//checking to see if knight is on g or h file
long spot4Clip = Lookups.fileTables[3] & Lookups.fileTables[Lookups.fileTables.length-2] & knightLocation;
long spot5Clip = spot4Clip;
long spot6Clip = spot3Clip;
long spot7Clip = spot2Clip;
long spot8Clip = spot1Clip;
long spot1 = spot1Clip <<6;
long spot2 = spot2Clip <<15;
long spot3 = spot3Clip <<17;
long spot4 = spot4Clip <<10;
long spot5 = spot5Clip >> 6;
long spot6 = spot6Clip >> 15;
long spot7 = spot7Clip >>17;
long spot8 = spot8Clip >>10;
long knightPsuedos = spot1 | spot2 | spot3 | spot4 | spot5 | spot6| spot7 | spot8;
long knightLegals = knightPsuedos & ~allPieces;
long knightAttacks = knightPsuedos & enemySide;
return new long[]{knightLegals,knightAttacks};
}
说这个方法return长的
1000000000000000000000000000000000000000000000000000000000000000
表示马可以攻击棋盘的右上角,我的一些方法采用此方法,如果直接从该方法中取 return 长,则 return null。如果我在方法中手动键入这么长的内容,它会给出错误“长数字太大”。这是一个方法的示例,当直接从另一个方法传递 long 时,它只是 returns 空值,或者如果 long 是手动输入则抛出错误:
public static ArrayList<Integer> indexSetBits(Long bitboard){
ArrayList<Integer> indices = new ArrayList<>();
int count =0;
while(bitboard >0L){
if((bitboard & 1L) == 1L){
indices.add(count);
}
bitboard >>= 1;
count++;
}
return indices;
}
我知道我传入的内容太大并且缺少二进制文字,为什么它不一致,我该如何解决?例如,此方法适用于我在上面放的一个例子 long:
public static void printBitBoard(long pieceBoard) {
String full = "";
//String square = rank *8 + file;
String s = Long.toBinaryString(pieceBoard);
//System.out.println(64 - Long.toBinaryString(pieceBoard).length());
if (Long.toBinaryString(pieceBoard).length() == 64) {
full = Long.toBinaryString(pieceBoard);
s = full;
} else {
full = String.format("%0" + (64 - Long.toBinaryString(pieceBoard).length()) + 'd', 0);
s = full + "" + s;
}
System.out.println(s);
int[][] board = new int[8][8];
int p = 0;
for (int rank = 0; rank < 8; rank++)
for (int file = 7; file >=0; file--) {
board[rank][file] = Integer.parseInt(s.substring(p, p + 1));
p++;
}
//prints 2d array representation of the bitboard, making it look like a chessboard.
for (int[] array : board) {
System.out.println(Arrays.toString(array));
}
}
如何确定方法 returning 是一个二进制文字而不是一个 long,为什么这个错误只出现在一种方法中而不是另一种方法中?谢谢。
1000000000000000000000000000000000000000000000000000000000000000
这在二进制表示中写得很清楚。您要求使用 Long.toBinaryString(pieceBoard)
.
当您编写此 java 代码时:
long x = 1000000000000000000000000000000000000000000000000000000000000000;
它不会编译,因为 java 默认为十进制表示。所以这是一个 多 的数字(就像 Long.toBinaryString(16)
打印 10000
)。
要解决这个问题,您需要将其转换为十进制。或者,更好的是,十六进制 - 这更容易阅读,并且因为十六进制以 16 为一组工作,可以很好地分为 2(例如,二进制是以 2 为底,即 2),因此很容易做到这一点。这是完全相同的数字,但为十六进制:
long x = 0x8000000000000000;
现在我们还有最后一个问题:java 的原始数据类型中的 所有 ,除了 char
,都是 签名的 和 数字 。因此,0x8000000000000000
只是 9223372036854775808 的另一种写法,它太大了 - long 有 64 位,因此可以表示 2^64 个值(基础数学),并且 long
数据类型是规定的,根据 java 规范,表示从 -9223372036854775808 到 + 9223372036854775807 的数字。(从 -2^63 到 +2^63-1)。
在 java 中没有办法写这样的文字并要求 java 将 is 解释为 'sequence of bits, most significant to least significant'。只有:“这是一个数字,使用 2 的补码将其解释为位序列,然后这就是该文字在评估时应解析的内容”。
换句话说,使用文字来表示您拥有的那个位串的方式是完全不切实际的。你必须写 -9223372036854775808,这是一个没有上下文的神秘数字。
所以,不要。 'I have this stream of bits stated in 1 and 0 symbols, please turn it into a long' 的工作不能用文字来完成。它是通过实用方法完成的,就像您使用 Long.toBinaryString
:
的方式一样
long x = Long.parseUnsignedLong("1000000000000000000000000000000000000000000000000000000000000000", 2);
System.out.printf("%x\n", x);
System.out.println(x);
System.out.println(Long.toBinaryString(x));
> 8000000000000000
> -9223372036854775808
> 1000000000000000000000000000000000000000000000000000000000000000
所以我正在写一个国际象棋引擎。我对每个棋子的移动都有单独的方法,return 一个大小为 2 的长数组,包括移动掩码和攻击掩码的长表示。问题是,由于某种原因,当 piece move 方法生成一个 long 且索引设置为 MSB 时,我的其他方法与此输入不一致。这是以骑士为例的代码。
public long[] calculateKnightMoves(int square, long ownSideBitboard,long enemySide, long allPieces){
/*
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 2, 0, 3, 0, 0]
[0, 0, 1, 0, 0, 0, 4, 0]
[0, 0, 0, 0, x, 0, 0, 0]
[0, 0, 8, 0, 0, 0, 5, 0]
[0, 0, 0, 7, 0, 6, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
*/
//8 possible moves for a knight, depending on which file you are on. Cannot move into a discovered check for your own king.
long knightLocation = 1L<<square;
//checking to see if knight is on a or b file
long spot1Clip = Lookups.fileTables[0] & Lookups.fileTables[1] & knightLocation;
//checking to see if knight is on a file
long spot2Clip = Lookups.fileTables[0] & knightLocation;
//checking to see if knight is on h file
long spot3Clip = Lookups.fileTables[Lookups.fileTables.length-2] & knightLocation;
//checking to see if knight is on g or h file
long spot4Clip = Lookups.fileTables[3] & Lookups.fileTables[Lookups.fileTables.length-2] & knightLocation;
long spot5Clip = spot4Clip;
long spot6Clip = spot3Clip;
long spot7Clip = spot2Clip;
long spot8Clip = spot1Clip;
long spot1 = spot1Clip <<6;
long spot2 = spot2Clip <<15;
long spot3 = spot3Clip <<17;
long spot4 = spot4Clip <<10;
long spot5 = spot5Clip >> 6;
long spot6 = spot6Clip >> 15;
long spot7 = spot7Clip >>17;
long spot8 = spot8Clip >>10;
long knightPsuedos = spot1 | spot2 | spot3 | spot4 | spot5 | spot6| spot7 | spot8;
long knightLegals = knightPsuedos & ~allPieces;
long knightAttacks = knightPsuedos & enemySide;
return new long[]{knightLegals,knightAttacks};
}
说这个方法return长的
1000000000000000000000000000000000000000000000000000000000000000
表示马可以攻击棋盘的右上角,我的一些方法采用此方法,如果直接从该方法中取 return 长,则 return null。如果我在方法中手动键入这么长的内容,它会给出错误“长数字太大”。这是一个方法的示例,当直接从另一个方法传递 long 时,它只是 returns 空值,或者如果 long 是手动输入则抛出错误:
public static ArrayList<Integer> indexSetBits(Long bitboard){
ArrayList<Integer> indices = new ArrayList<>();
int count =0;
while(bitboard >0L){
if((bitboard & 1L) == 1L){
indices.add(count);
}
bitboard >>= 1;
count++;
}
return indices;
}
我知道我传入的内容太大并且缺少二进制文字,为什么它不一致,我该如何解决?例如,此方法适用于我在上面放的一个例子 long:
public static void printBitBoard(long pieceBoard) {
String full = "";
//String square = rank *8 + file;
String s = Long.toBinaryString(pieceBoard);
//System.out.println(64 - Long.toBinaryString(pieceBoard).length());
if (Long.toBinaryString(pieceBoard).length() == 64) {
full = Long.toBinaryString(pieceBoard);
s = full;
} else {
full = String.format("%0" + (64 - Long.toBinaryString(pieceBoard).length()) + 'd', 0);
s = full + "" + s;
}
System.out.println(s);
int[][] board = new int[8][8];
int p = 0;
for (int rank = 0; rank < 8; rank++)
for (int file = 7; file >=0; file--) {
board[rank][file] = Integer.parseInt(s.substring(p, p + 1));
p++;
}
//prints 2d array representation of the bitboard, making it look like a chessboard.
for (int[] array : board) {
System.out.println(Arrays.toString(array));
}
}
如何确定方法 returning 是一个二进制文字而不是一个 long,为什么这个错误只出现在一种方法中而不是另一种方法中?谢谢。
1000000000000000000000000000000000000000000000000000000000000000
这在二进制表示中写得很清楚。您要求使用 Long.toBinaryString(pieceBoard)
.
当您编写此 java 代码时:
long x = 1000000000000000000000000000000000000000000000000000000000000000;
它不会编译,因为 java 默认为十进制表示。所以这是一个 多 的数字(就像 Long.toBinaryString(16)
打印 10000
)。
要解决这个问题,您需要将其转换为十进制。或者,更好的是,十六进制 - 这更容易阅读,并且因为十六进制以 16 为一组工作,可以很好地分为 2(例如,二进制是以 2 为底,即 2),因此很容易做到这一点。这是完全相同的数字,但为十六进制:
long x = 0x8000000000000000;
现在我们还有最后一个问题:java 的原始数据类型中的 所有 ,除了 char
,都是 签名的 和 数字 。因此,0x8000000000000000
只是 9223372036854775808 的另一种写法,它太大了 - long 有 64 位,因此可以表示 2^64 个值(基础数学),并且 long
数据类型是规定的,根据 java 规范,表示从 -9223372036854775808 到 + 9223372036854775807 的数字。(从 -2^63 到 +2^63-1)。
在 java 中没有办法写这样的文字并要求 java 将 is 解释为 'sequence of bits, most significant to least significant'。只有:“这是一个数字,使用 2 的补码将其解释为位序列,然后这就是该文字在评估时应解析的内容”。
换句话说,使用文字来表示您拥有的那个位串的方式是完全不切实际的。你必须写 -9223372036854775808,这是一个没有上下文的神秘数字。
所以,不要。 'I have this stream of bits stated in 1 and 0 symbols, please turn it into a long' 的工作不能用文字来完成。它是通过实用方法完成的,就像您使用 Long.toBinaryString
:
long x = Long.parseUnsignedLong("1000000000000000000000000000000000000000000000000000000000000000", 2);
System.out.printf("%x\n", x);
System.out.println(x);
System.out.println(Long.toBinaryString(x));
> 8000000000000000
> -9223372036854775808
> 1000000000000000000000000000000000000000000000000000000000000000