我创建了一个函数,该函数返回存储长值所需的字节数。该值必须位于[Long.MIN_VALUE, Long.MAX_VALUE].
private static final int ONE_BYTE_MAX = (1 << 7) - 1; // 127
ONE_BYTE_MAX的值为127
private static final int ONE_BYTE_MIN = -(1 << 7); // -128
ONE_BYTE_MIN的值为-128
private static final int TWO_BYTE_MAX = (1 << 15) - 1;
private static final int TWO_BYTE_MIN = -(1 << 15);
private static final int THREE_BYTE_MAX = (1 << 23) - 1;
private static final int THREE_BYTE_MIN = -(1 << 23);
private static final long FOUR_BYTE_MAX = (1L << 31) - 1;
private static final long FOUR_BYTE_MIN = -(1L << 31);
private static final long FIVE_BYTE_MAX = (1L << 39) - 1;
private static final long FIVE_BYTE_MIN = -(1L << 39);
private static final long SIX_BYTE_MAX = (1L << 47) - 1;
private static final long SIX_BYTE_MIN = -(1L << 47);
private static final long SEVEN_BYTE_MAX = (1L << 55) - 1;
private static final long SEVEN_BYTE_MIN = -(1L << 55);
方法
public static int getBytesForLongValue(long value) {
if (value >= ONE_BYTE_MIN && value <= ONE_BYTE_MAX) {
return 1;
} else if (value >= TWO_BYTE_MIN && value <= TWO_BYTE_MAX) {
return 2;
} else if (value >= THREE_BYTE_MIN && value <= THREE_BYTE_MAX) {
return 3;
} else if (value >= FOUR_BYTE_MIN && value <= FOUR_BYTE_MAX) {
return 4;
}else if (value >= FIVE_BYTE_MIN && value <= FIVE_BYTE_MAX) {
return 5;
}else if (value >= SIX_BYTE_MIN && value <= SIX_BYTE_MAX) {
return 6;
}else if (value >= SEVEN_BYTE_MIN && value <= SEVEN_BYTE_MAX) {
return 7;
} else {
return 8;
}
}
在Java中有一种简单的方法
答案 0 :(得分:3)
尽管我认为对于Java中的长原始类型,我们应该将字节数保留为8,但是还有另一种方法来计算保留长值(包括符号位)的最小字节数。同样,该方法也可以用于计算任何整数的大小,从而调整方法的签名:
public static int getMinNoOfBytes(BigInteger value)
不过,这里是代码:
public class Answer {
public static int getMinNoOfBytes(long value) {
BigInteger any = BigInteger.valueOf(value);
return any.toByteArray().length;
}
//Test
public static void main(String[] args) {
//Long.MAX_VALYE
System.out.println(getMinNoOfBytes(Long.MAX_VALUE));
//Long.MIN_VALUE
System.out.println(getMinNoOfBytes(Long.MIN_VALUE));
//Any value
System.out.println(getMinNoOfBytes(65536));
}
}
输出是(按预期)
8 8 3
答案 1 :(得分:1)
您可以创建一个包含两个字段的枚举:最小值和最大值。然后遍历该枚举值,并在循环内只有一个if语句:
public enum Range {
ONE (1, -(1L << 7 ), (1L << 7 ) - 1),
TWO (2, -(1L << 15), (1L << 15) - 1),
THREE(3, -(1L << 23), (1L << 23) - 1),
FOUR (4, -(1L << 31), (1L << 31) - 1),
FIVE (5, -(1L << 39), (1L << 39) - 1),
SIX (6, -(1L << 47), (1L << 47) - 1),
SEVEN(7, -(1L << 55), (1L << 55) - 1);
public final int bytesNeeded;
public final long min;
public final long max;
Range(int bytesNeeded, long min, long max) {
this.bytesNeeded = bytesNeeded;
this.min = min;
this.max = max;
}
public static int getNbBytesForLongValue(long value) {
for (Range range : Range.values()) {
if (range.min <= value && value <= range.max) {
return range.bytesNeeded;
}
}
return 8;
}
}
编辑:
看看这些枚举定义,实际上很容易将其完全转换成循环:
public static int getNbBytesForLongValue(long value) {
for (int i = 0; i < 7; i++) {
if (-(1L << (7 + i * 8)) <= value && value <= (1L << (7 + i * 8)) - 1) {
return i + 1;
}
}
return 8;
}
答案 2 :(得分:1)
您需要找到最高的1位,然后知道可能需要多少字节。
可以使用方法Long.numberOfLeadingZeros(long i)
。
由于长整数有Long.SIZE
位(实际上是64位),因此很容易计算,但是您需要对零值和负值进行特殊处理。
public static int getNbBytesForLongValue1(long value) {
if (value == 0)
return 1;
int bitLength;
if (value > 0) {
int leadingZeroes = Long.numberOfLeadingZeros(value);
bitLength = Long.SIZE - leadingZeroes + 1/*positive sign bit*/;
} else {
int leadingOnes = Long.numberOfLeadingZeros(value ^ -1L);
bitLength = Long.SIZE - leadingOnes + 1/*negative sign bit*/;
}
return (bitLength + 7) / 8; // round up to whole bytes
}
可以缩短为(如果您想让自己有点晦涩):
public static int getNbBytesForLongValue(long value) {
return (value == 0 ? 1 : ((Long.SIZE - Long.numberOfLeadingZeros(value > 0 ? value : value ^ -1L)) >> 3) + 1);
}
一行代码的解决方案,没有循环。
答案 3 :(得分:1)
在此答案中,我们重点关注所需的位数。从那以后,可以通过将ceil除以8来计算字节数。
int bytesNeeded(long number) {
return (bitsNeeded(number) + 7) / 8;
}
我假设我们将所有数字都存储在二进制补码中,因此我们需要5位而不是4位来存储数字8 dec = 0 1000 bin 等。
long
int bitsNeeded(long number) {
if (number < 0) {
number = ~number; // same as -(number + 1)
}
return Long.SIZE - Long.numberOfLeadingZeros(number) + 1;
}
i | bitsNeeded(i) | binary representation of i in two's complement
---+---------------+-----------------------------------------------
-8 | 4 | 1000
-7 | 4 | 1001
-6 | 4 | 1010
-5 | 4 | 1011
-4 | 3 | 100
-3 | 3 | 101
-2 | 2 | 10
-1 | 1 | 1
0 | 1 | 0
1 | 2 | 01
2 | 3 | 011
3 | 3 | 011
4 | 4 | 0100
5 | 4 | 0101
6 | 4 | 0110
7 | 4 | 0111
8 | 5 | 01000
如果您对更大的数字感兴趣,可以将它们存储在BigInteger
中。幸运的是,BigInteger
为您提供了一种非常方便的方法:
int bitsNeeded(BigInteger number) {
return number.bitLength() + 1;
}
如果您不关心大数字,但想使用bitLength()
,请使用
int bitsNeeded(long number) {
return BigInteger.valueOf(number).bitLength() + 1;
}
答案 4 :(得分:0)
将Long
转换为Binary String
,然后获得length
中的String
。
public static int getNbBytesForLongValue(long value) {
int length = Long.toBinaryString(value).length();
int noOfByte = length%8 == 0 ? length/8 : (length/8 + 1);
return noOfByte;
}
注意:负数存储为2的称赞。因此,-10
将存储为1111111111111111111111111111111111111111111111111111111111110110
。因此,您将获得8
作为输出(正确)而不是2
。
答案 5 :(得分:0)
您可以使用for
循环将参数除以128,然后计算达到0所需的迭代次数。
public int countBytesNeeded(long l) {
if (l == 0) {
return 1;
}
int result = 0;
for (; l != 0; result++) {
l = l / 128;
}
return result;
}