What is the equivalent of unsigned long in java - java

i have written these following three functions for my project to work:
WORD shuffling(WORD x)
{
// WORD - 4 bytes - 32 bits
//given input - a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15- b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15
//output required - a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7 - a8,b8,a9,b9,a10,b10,a11,b11,a12,b12,a13,b13,a14,b14,a15,b15
x = (x & 0X0000FF00) << 8 | (x >> 8) & 0X0000FF00 | x & 0XFF0000FF;
x = (x & 0X00F000F0) << 4 | (x >> 4) & 0X00F000F0 | x & 0XF00FF00F;
x = (x & 0X0C0C0C0C) << 2 | (x >> 2) & 0X0C0C0C0C | x & 0XC3C3C3C3;
x = (x & 0X22222222) << 1 | (x >> 1) & 0X22222222 | x & 0X99999999;
return x;
}
WORD t_function(WORD n)
{
WORD t_result=0;
WORD64 var = 2*((n*n)& 0xFFFFFFFF)+n; // (n*n mod FFFFFFFF) becomes a 32-bit word
t_result = (WORD) ((var)& 0xFFFFFFFF);
return t_result;
}
WORD lfsr(WORD t_result)
{
WORD returnValue = t_result;
WORD flag = 0;
flag = returnValue & 0x80000000; // Checking if MSB is 1 or 0
// Left shift the input
returnValue = returnValue << 1;
// If MSB is 1 then XOR the reult with the primitive polynomial
if(flag > 0)
{
returnValue = returnValue ^ 0x4C11DB7;
}
return returnValue;
}
WORD - unsigned long
this code is in "c". Now i have to implement this in java. Everything is fine in compiling and running the code. But here i used unsigned long and in java i have used int Since i am operating on 32bits at a time. The problem is "when implementing in java whenever the result is going out of range of int the output is being deviated and it will not be the same output from the c code. Is there any solution for my problem to replace the unsigned long range values in java

Update – Java 8 can treat signed int & long as if unsigned
In Java, the primitive integer data types (byte, short, int, and long) are signed (positive or negative).
As of Java 8 both int and long can be treated explicitly as if they are unsigned. Officially a feature now, but kind of a hack nonetheless. Some may find it useful in certain limited circumstances. See the Java Tutorial.
int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -2³¹ and a maximum value of 2³¹-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2³²-1. Use the Integer class to use int data type as an unsigned integer. See the section The Number Classes for more information. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
long: The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -2⁶³ and a maximum value of 2⁶³-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2⁶⁴-1. The unsigned long has a minimum value of 0 and maximum value of 2⁶⁴-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.
I am not necessarily recommending this approach. I’m merely making you aware of the option.

Short answer, there's no unsigned data type in java. long in C is 32-bit on 32-bit systems, but java's long is 64-bit, so you can use that for replacement (at least it would solve the overflow problem). If you need even wider integers, use BigInteger class.

Look over Java's Primitive Data Types. If you need something bigger than a long, try a BigInteger.

Related

Java - Copy integer to long

I have an external system outputting 2 unsigned integers that represent a 64 bit unsigned int. Java picks these up and converts them to signed integers. I have called them lower and upper in java. I would like to put this back into a 64 bit int. I understand I have to use signed int which is ok.
I started off casting them both to long, shift the upper long by 32 bits and then trying to add them but it didn't go so well because the cast moves the sign bit of the integers. So I started to muck around with adding 2^31 and other messy stuff. How can I do this cleanly?
Here is an example, using 2 x 8 bit numbers to 16 bits for simplicity
Higher = 00000000 lower = 11111111
Desired result
0000000011111111
Result I get
1000000001111111
EDIT: This is code that I believe works ok (I haven't fully tested) but I was hoping for something cleaner.
private static long combineCounters(int lower, int upper) {
long lower2 = (long)lower;
if(lower2 < 0) lower2 += (2L<<31);
long upper2 = (long)upper;
if(upper2 < 0) upper2 += (2L<<31);
long result = lower2 | (upper2<<32);
return result;
}
For your case, first of all, you should store your integer values correctly into a long. To do so, you can AND your value with 0xFFFFFFFFL (a long with first 32 bit as 1).
Here is an example which works:
int upperInt = ...
int lowerInt = ...
long hi = upperInt & 0xFFFFFFFFL;
long lo = lowerInt & 0xFFFFFFFFL;
long c = (hi << 32) | lo;
System.out.println(String.format("0x%X", c));
int higher = ...
int lower = ...
long result = (((long) higher) << 32) | ((long) lower) & 0xFFFFFFFFL;

Storing unsigned long value in two 16bit register

I want to store unsigned long value in two 16bit register.For example if I have long value (-2,147,483,648 to 2,147,483,647) then I'm using formula like:
v[0] = myValue % 65536
v[1] = myValue / 65536
To get value from register
outVal = reg0 + (reg1 * 65536)
But how to do for unsigned long which value range is from 0 to 4,294,967,295?
As commenter harold pointed out already, your formula doesn't even work correctly for negative numbers.
You should do it bitwise instead of using math to avoid surprises (and speed things up in case the compiler didn't optimize it for you already).
Splitting:
v[0] = myValue & 0xFFFF
v[1] = myValue >> 16 // this implicitly cuts off the lower 16 bits
// by shifting them away into the nirvana
Joining:
outVal = reg0 | (reg1 << 16)
This now applies to both signed and unsigned (provided that all your variables have the same "sign type").
Legend, in case your language (which you didn't specify) uses different operators:
& is bitwise AND, | is bitwise OR, << and >> are bitwise shifting left/right (SHL/SHR), 0x marks a hexadecimal literal (you could use 65536 instead of 0xFFFF, but I think the hex literal makes it clearer where this magic number comes from).

Convert 32 bit fixed point value

In my Java application I need to interpret a 32 Bit Fixed Point value. The number format is as follows: The first 15 bits describe the places before the comma/point, the 16th bit represents the sign of the value and the following 16 bits describe the decimal places (1/2,1/4,1/8,1/16,...).
The input is a byte array with four values. The order of the bits in the byte array is little endian.
How can I convert such a number into Java float ?
Just do exactly what it says. Assume x is the 32bit fixed point number as int.
So, put the bits after the point, after the point, and don't use the sign here:
float f = (float)(x & 0x7fff_ffff) / (float)(1 << 16);
Put back the sign:
return x < 0 ? -f : f;
You will lose some precision. A float does not have 31 bits of precision, but your input does. It's easily adapted to doubles though.
Since the sign bit is apparently really in the middle, first get it out:
int sign = x & (1 << 16);
Join the two runs of non-sign bits:
x = (x & 0xFFFF) | ((x >> 1) & 0x7fff0000);
Then do more or less the old thing:
float f = (float)x / (float)(1 << 16);
return sign == 0 ? f : -f;
In case your input is little endian format, use the following approach to generate x:
int x = ByteBuffer.wrap(weirdFixedPoint).order(ByteOrder.LITTLE_ENDIAN).getInt();
where weirdFixedPoint is the byte array containing the 32 bit binary representation.

What is a the quickest way to bitwise convert two ints to a long in java?

I've been using images to store data, since editing binary data through Paint.net is much friendlier than most hex editors.
However, some of my data is long integers. Long integers are twice the size of a 32-bit integer in java, 64-bits. How does one get the long to two integers, and more importantly, back to a long when reading the image? Since Java does not have unsigned ints, the top bit of the integer or long is the negative sign bit, even though bit 32 (the lower integer/pixel) will be an ordinary bit in the long integer.
Most methods of converting long to int discard the upper bits, as well, which will or may contain bitwise (binary) information!
What I need to do is
Transform a single long into two integers that faithful contain its bit data
Transform two integers back into a long that faithfully contains their bit data.
No need to use Autoboxing (Long, Integer, etc.). Primitives work just fine. The following is the best you can do in the Java programming language.
Join
Combining two ints into a long
int lo; // Integer to fill lower bits
int hi; // Integer to fill upper bits
long val = (((long) hi) << 32) | (lo & 0xffffffffL);
 
Split
Retrieving the (upper) bits 31-16
int hi = (int) (val >> 32);
Retrieving the (lower) bits 15-0
int lo = (int) val;
 
Note:
Be aware of the difference between:
n >> 32 (Sign-extend right-shift)
n >>> 32 (Zero-fill right-shift)
Since Java used only signed bits, the >>> operator was introduced to handle integers as if they were "unsigned".
int u,v
long n = u;
if (v < 0) { ++n; }
n <<= 32;
n += v;
You'll either need to make two new longs with the same values or you can typecast the integers.
int x = 0;
(long) int x = 2;
This declares a new integer with a set value of 0 and then changes the value to 2 once it becomes a long.
Simple response, but i hope it helps

unsigned long in java, using BigInteger for arithmetics, but BigInteger.toByteArray returns 14 bytes instead of 8

I have the following c code which id like to port to Java
unsigned long long* data=(unsigned long long*)pBuffer; // file data
unsigned long long crypt = 0x0000;
unsigned long long next_crypt;
unsigned int len = size >> 3;
for(unsigned int i=0; i<len;i++) {
next_crypt = crypt+data[i]-0xCAFEBABE;
data[i] = ((data[i]<<0x1d)|(data[i]>>0x23))+0xCAFEBABE;
data[i] = (data[i]<<0x0e)|(data[i]>>0x32);
data[i] = data[i] - crypt;
crypt = next_crypt;
}
I tried to port this to java using long, however this would result in negative values. Therefor i switched to biginteger since i have to do arithmetics (bit shifting etc).
I got the desired 64bit unsigned long value using BigInteger, however when i wanted to convert it to byte (BigInteger.toByteArray) it was 14 bytes long and no longer 8 bytes - so i cannot modify my array/file anymore. I tried using toLongValue() but the data was incorrect.
Thanks
Your C code is relying on bits being shifted off the high-order end of the unsigned long long. (These are rotated around to the other end by the other shift.) BigInteger is arbitrary precision and hence has no end, so left-shifted bits are never shifted off.
You could construct a 64-bit BigInteger bitwise AND mask and AND it after the left shifts. This is an intuitive solution.
You could also just simply ignore the high-order bytes.
byte[] bar = foo.toByteArray();
if (bar.length > 8) {
bar = System.arrayCopy(bar, bar.length - 8, new byte[8], 0, 8);
}
If len is large, then this simple solution would be wasteful of memory.
In any case there is a saner and higher-performing solution. Java's signed integer types are all guaranteed to have two's complement semantics. The bit semantics for arithmetic with two's complement integers and unsigned integers are identical--the difference is only in the interpretation of the value! So just use the original C code (substituting in Java's long) and at the end, interpret them your way.
byte[] longToByteArray(long x) {
byte[] array = new byte[8];
for (int i = 7; i >= 0; i--) {
array[i] = (byte)x;
x >>>= 8;
}
}
By the way, be sure you replace the >> operator in the C code with Java's >>> operator.
The nice thing about Java is that it's guaranteed to be twos-complement, so provided you use >>> instead of >> and avoid % and / and inequalities, arithmetic is effectively unsigned anyway.

Categories