Converting Long number to byte array - java

I am trying to convert a long number (convertex from Hex to Long) to a byte array. I'm trying the following code:
ByteBuffer b = ByteBuffer.allocate(4);
// The literal 4328719365 of type int is out of range
b.putLong(4328719365);
byte[] result = b.array();
but it's not compiling due to being out of range for int.
What can I do to solve this issue?

Suffix L (or l) converts literal number to a long.
So try this:
b.putLong(4328719365L);
You can use literal long value just like number without L suffix. Like assign them to variables:
long myLongValue = 4328719365L;
b.putLong(myLongValue);

1) Suffix L to the value
2) Increase the ByteBuffer allocated size and try
3) Int will take max of 10 digits and putLong might internally add L and making it beyond 10. Please check reducing digits in number.

Related

Inserting unsigned integer value into bytebuffer, maintaining binary representation

I'm trying to put the following binary representation into a bytebuffer for 4 bytes. But since Java doesn't do unsigned, I'm having trouble: 11111111000000001111111100000000
ByteBuffer bb = ByteBuffer.allocate(8);
bb.putInt(Integer.parseInt("11111111000000001111111100000000", 2));
//throws numberformatexception
Negating the most significant bit seems to change the binary string value because of how two's compliment works:
bb.putInt(Integer.parseInt("-1111111000000001111111100000000", 2));
System.out.println(Integer.toBinaryString(bb.getInt(0)));
//prints 10000000111111110000000100000000
It's important that the value is in this binary format exactly because later it will be treated as an unsigned int. How should I be adding the value (and future values that start with 1) to the bytebuffer?
Just parse it as a long first, and cast the result:
int value = (int) Long.parseLong("11111111000000001111111100000000", 2);
That handles the fact that int runs out of space, because there's plenty of room in a long. After casting, the value will end up as a negative int, but that's fine - it'll end up in the byte buffer appropriately.
EDIT: As noted in comments, in Java 8 you can use Integer.parseUnsignedInt("...", 2).
You can also use Guava's UnsignedInts.parseUnsignedInt(String string, int radix) and UnsignedInts.toString(int x,int radix) methods:
int v = UnsignedInts.parseUnsignedInt("11111111000000001111111100000000", 2);
System.out.println(UnsignedInts.toString(v, 2));
try this
bb.putInt((int)Long.parseLong("11111111000000001111111100000000", 2));

what is 0x00FFFFFFFFFFFFFFL?

Hi i am trying to understand how the range encoder works so i found a java program for range encoder then when i was trying to reverse engineer the code where i came across the value 0x00FFFFFFFFFFFFFFL, i would appreciate if any one can tell why we use this value ?
public class RangeCoder64
{
static final protected long Top=1L<<48;
static final protected long Bottom=1L<<40;
static final protected long MaxRange=Bottom;
protected long Low=0;
protected long Range=0x00FFFFFFFFFFFFFFL;
}
0x represents the value is hexadecimal.
L indicates the literal is a long value.
Basically it's just a large number. (Decimal value is 72057594037927935)
0x00FFFFFFFFFFFFFFL is 0x + 00FFFFFFFFFFFFFF + L
0x denotes hex is used
00FFFFFFFFFFFFFF is hex for 72,057,594,037,927,935
L means that the value is of size Long -- smaller numbers do not need it (below size requiring Long)
When you see a value that is 1 less than a power of 2, it will be right filled with 1's and therefore in hex will be right filled with Fs. Genertally, it will be used as a mask, that mask when anded with a value will keep only the low bits, in this case it will discard the highest byte, and keep the 7 low bytes.
It would be the value of that range. It looks like 7 bytes. So for some reason it is restricting the number.

How do i store numbers bigger than 10 billion

I am making a program and i need a way to make variables go over 10 billion and int only stores up to 999 million for me so i decided to use a long instead of a int and it turn out it only stores up to 999 million as well.
int TotalWorldPop = 7200000000;
gives me the "literal is out of range" error
long TotalWorldPop = 7200000000;
gives me the "literal is out of range" error as well
but
int TotalWorldPop = 999999999
is ok for me
A long can accommodate numbers as large as 263-1. But there's a trick to putting them into the primitive field.
If you're entering the primitive literal, then you have to add an L at the end, as all numeric literals are treated as int (and it can only go up to ~2.1 billion).
If you need numbers larger than that, use BigInteger.
You could use a BigInteger to store very large numbers.
Example:
Biginteger bigInt1 = new Biginteger("91826581752671985235272769716");
Biginteger bigInt2 = new Biginteger("-1796357891266373473772242");
Biginteger bigint3 = bigInt1.divide(bigInt2);
Biginteger bigint4 = bigInt1.add(bigInt2);

Java parsing long from string

I'm currently trying to parse some long values stored as Strings in java, the problem I have is this:
String test = "fffff8000261e000"
long number = Long.parseLong(test, 16);
This throws a NumberFormatException:
java.lang.NumberFormatException: For input string: "fffff8000261e000"
However, if I knock the first 'f' off the string, it parses it fine.
I'm guessing this is because the number is large and what I'd normally do is put an 'L' on the end of the long to fix that problem. I can't however work out the best way of doing that when parsing a long from a string.
Can anyone offer any advice?
Thanks
There's two different ways of answering your question, depending on exactly what sort of behavior you're really looking for.
Answer #1: As other people have pointed out, your string (interpreted as a positive hexadecimal integer) is too big for the Java long type. So if you really need (positive) integers that big, then you'll need to use a different type, perhaps java.math.BigInteger, which also has a constructor taking a String and a radix.
Answer #2: I wonder, though, if your string represents the "raw" bytes of the long. In your example it would represent a negative number. If that's the case, then Java's built-in long parser doesn't handle values where the high bit is set (i.e. where the first digit of a 16 digit string is greater than 7).
If you're in case #2, then here is one (pretty inefficient) way of handling it:
String test = "fffff8000261e000";
long number = new java.math.BigInteger(test, 16).longValue();
which produces the value -8796053053440. (If your string is more than 16 hex digits long, it would silently drop any higher bits.)
If efficiency is a concern, you could write your own bit-twiddling routine that takes the hex digits off the end of the string two at a time, perhaps building a byte array, then converting to long. Some similar code is here:
How to convert a Java Long to byte[] for Cassandra?
The primitive long variable can hold values in the range from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 inclusive.
The calculation shows that fffff8000261e000 hexademical is 18,446,735,277,656,498,176 decimal, which is obviously out of bounds. Instead, fffff8000261e000 hexademical is 1,152,912,708,553,793,536 decimal, which is as obviously within bounds.
As everybody here proposed, use BigInteger to account for such cases. For example, BigInteger bi = new BigInteger("fffff8000261e000", 16); will solve your problem. Also, new java.math.BigInteger("fffff8000261e000", 16).toString() will yield 18446735277656498176 exactly.
The number you are parsing is too large to fit in a java Long. Adding an L wouldn't help. If Long had been an unsigned data type, it would have fit.
One way to cope is to divide the string in two parts and then use bit shift when adding them together:
String s= "fffff8000261e000";
long number;
long n1, n2;
if (s.length() < 16) {
number = Long.parseLong(s, 16);
}
else {
String s1 = s.substring(0, 1);
String s2 = s.substring(1, s.length());
n1=Long.parseLong(s1, 16) << (4 * s2.length());
n2= Long.parseLong(s2, 16);
number = (Long.parseLong(s1, 16) << (4 * s2.length())) + Long.parseLong(s2, 16);
System.out.println( Long.toHexString(n1));
System.out.println( Long.toHexString(n2));
System.out.println( Long.toHexString(number));
}
Note:
If the number is bigger than Long.MAX_VALUE the resulting long will be a negative value, but the bit pattern will match the input.

Can we multiply two bytes directly by using * operator directly

I need to perform the following operation on a byte (2*x*x)+x where x is a single byte. Can i perform that operation directly as we will do for int. If no how can we perform above operation.
Have you tried the following?
byte x =
int f = 2 * x * x + x;
As an exercise I suggest you print out the results of every possibility byte value and see if you get the expected value. There is only 256 possible byte values.
Yes.
Java integer arithmetic is two-complement; that means that (as long there are enough bits to write down the values) lengthning or shortening the field does not affect the result.
NOTE1: Check for overflows. If the result is not in the 128 / -127 range it will not fit in a byte (or 255 / 0 for unsigned).
NOTE2: Float and double are not part of integer arithmetic.
So apparently you believe that the operator exists because the compiler allows it but you don't believe that the JVM will compute the result correctly. Why?
And how hard is this to test? Bytes only have 256 values each.
There can be two different cases:
byte a = 2; byte b = 2; byte c = a*b
it is correct but
byte a = 22; byte b = 22; byte c = a*b
it is not correct.
because while assigning value to a and b we given value less than 127 but after multiplication the value is longer than one byte that is why we need a bigger datatype to store value of c.
for that case you can use int c = a*b;

Categories

Resources