Equivalent of BigInteger value of C++ long long - java

I am migrating some code base from C++ to Java where I encountered a long long value in the C++ code which i need to migrate.
On some research i found out I should be using BigInteger to represent the long long of C++.
I looked at couple of examples and found out the syntax to be :
static BigInteger flag1 = BigInteger.valueOf(0x00000001);
Here i noticed the value used in the argument for BigInteger.valueOf is not the same as original long long value which was 0x0000000000000001LL
Original value had 16 digits and this one had 8 digits and does not include LL suffix at the end. Can someone explain what is going on ?
Also If they can suggest the value of 0x0000000000000200LL in similar terms.

Please note: all those zeros ... don't matter. There is no difference between 0x1; and 0x001, and so on. As long as we are talking about numbers.
It would be a different thing if those were represented as strings; then of coursre "0x1" is not the same string as "0x01". But well, they aren't.
All of your values are number literals; and they are all in a range that would even fit into ordinary long values in Java.
In other words: leading zero digits do not matter for numbers (except for an example like 010, which is something else than 10; as starting 0 indicate octal numbers).
The more interesting question would actually would be: what literal value the compiler puts into the java bytecode for that.

0x0000000000000001LL == 0x00000001 == 0x1 == 1 (dec)
0x0000000000000200LL == 0x00000200 == 0x200 = 512 (dec)
Those are small values and can be represented as a regular int.
You can also use BigInteger is you need.

There are a number of things to learn here:
You probably don't need to use BigInteger here at all. The C++ long long type is a signed 64 bit integer on most systems (see http://en.cppreference.com/w/cpp/language/types). But Java has a 64 bit signed integer type - long. So unless you are porting C++ code that was designed for an architecture where long long is greater than 64 bits (!), a Java long is what you need to use.
Leading zeros don't matter in hexadecimal literals (i.e. 0x...) in Java.
(They matter for decimal literals though, because a leading zero turns a "decimal" literal into an octal literal ... which alters its value. For instance, the literal 010 represents the number eight!)
If you actually do need 64 bit integer literal in Java, then put an L on the right hand end. Integer literals are assumed to be 32 bit.
In a context like this where you are trying to use BigInteger(long), a 32 bit integer literal would be widened to 64 bits anyway.
So in your case:
static BigInteger flag1 = BigInteger.valueOf(0x00000001);
static BigInteger flag1 = BigInteger.valueOf(0x0000000000000001);
static BigInteger flag1 = BigInteger.valueOf(0x1);
static BigInteger flag1 = BigInteger.valueOf(1);
static BigInteger flag1 = BigInteger.valueOf(1L);
are all saying the same thing. This is saying the same thing too ...
static BigInteger flag1 = BigInteger.valueOf(01);
... but it is a bad idea. It only works because "1" octal and "1" decimal are the same number.
Someone asked:
The more interesting question would actually would be: what literal value the compiler puts into the java bytecode for that.
I don't think that the JLS specifies this, but it would use a long literal because that is what the JVM spec requires.

Related

claims long is out of bounds [duplicate]

I am working with data types at the moment in Java, and if I have understood correctly the type long accepts a value between the ranges of -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. Now as you can see below, I have create a long variable called testLong, although when I insert 9223372036854775807 as the value, I get an error stating:
The literal 9223372036854775807 of the type int is out of range.
I don't know why it is referring to the long data type as an int.
Anyone have any ideas?
Code:
char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;
Add a capital L to the end:
long value = 9223372036854775807L;
Otherwise, the compiler will try to parse the literal as an int, hence the error message
I don't know why it is referring to the long data type as an int
It is not. You should learn to trust compiler messages (especially when they are from sane, modern compilers and not ancient compilers that tended to have bad error messages). While the language that they speak might be hard to decipher at times, they are not usually lying to you.
Let's look at it again:
The literal of int 9223372036854775807 is out of range.
Note, that it doesn't mention your variable testLong or the type long anywhere, so the problem is not about the initialization. It seems to occur at some other point.
Now lets investigate some of the parts of the message:
int tells us that he wants to treat something as an int value (which is not what you wanted!)
"out of range" is pretty clear: something is not within the expected range (probably that of int)
"The literal": now that's interesting: what is a literal?
I'll leave the cozy list to talk about literals for a moment: literals are places where you have some value in your code. There are String literals, int literals, class literals and so on. Every time you mention a value explicitly in your code, it's a literal.
So it's not actually nagging you about the variable declaration, but the number itself, the value is what it's nagging you about.
You can easily verify this by using the same literal in a context where a long and an int are equally acceptable:
System.out.println(9223372036854775807);
PrintStream.println can take either an int or a long (or pretty much anything else). So that code should be fine, right?
No. Well, maybe it should be, but according to the rules it is not fine.
The problem is that "some digits" is defined to be an int literal and therefore must be in the range defined by int.
If you want to write a long literal, then you must make that explicit by appending the L (or lower case l, but I highly suggest you always use the upper-case variant, because it's much easier to read and harder to mistake for a 1).
Note that a similar problem occurs with float (postfix F/f) and double (postfix D/d).
Side note: you'll realize that there are no byte or short literals and you can still assign values (usually int literals) to byte and short variables: that's possible due to special rules in § 5.2 about conversions in an Assignment Contexts: they allow assignment of constant expressions of a larger type to byte, short, char or int if the values are within the types range.
Try doing 9223372036854775807L. The L at the end tells Java that 9223372036854775807 is a long.
I had this problem in the past and I fixed that by writing the value in the scientific form.
for example:
double val = 9e300;
long ak = 34778754226788444L/l;
Both use but at a time only one use uppercase L or lowercase l.
Why use L/l? Because long is a part of integral datatype.

How do you make jgrasp ignore numbers over 1 billion? [duplicate]

I am working with data types at the moment in Java, and if I have understood correctly the type long accepts a value between the ranges of -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. Now as you can see below, I have create a long variable called testLong, although when I insert 9223372036854775807 as the value, I get an error stating:
The literal 9223372036854775807 of the type int is out of range.
I don't know why it is referring to the long data type as an int.
Anyone have any ideas?
Code:
char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;
Add a capital L to the end:
long value = 9223372036854775807L;
Otherwise, the compiler will try to parse the literal as an int, hence the error message
I don't know why it is referring to the long data type as an int
It is not. You should learn to trust compiler messages (especially when they are from sane, modern compilers and not ancient compilers that tended to have bad error messages). While the language that they speak might be hard to decipher at times, they are not usually lying to you.
Let's look at it again:
The literal of int 9223372036854775807 is out of range.
Note, that it doesn't mention your variable testLong or the type long anywhere, so the problem is not about the initialization. It seems to occur at some other point.
Now lets investigate some of the parts of the message:
int tells us that he wants to treat something as an int value (which is not what you wanted!)
"out of range" is pretty clear: something is not within the expected range (probably that of int)
"The literal": now that's interesting: what is a literal?
I'll leave the cozy list to talk about literals for a moment: literals are places where you have some value in your code. There are String literals, int literals, class literals and so on. Every time you mention a value explicitly in your code, it's a literal.
So it's not actually nagging you about the variable declaration, but the number itself, the value is what it's nagging you about.
You can easily verify this by using the same literal in a context where a long and an int are equally acceptable:
System.out.println(9223372036854775807);
PrintStream.println can take either an int or a long (or pretty much anything else). So that code should be fine, right?
No. Well, maybe it should be, but according to the rules it is not fine.
The problem is that "some digits" is defined to be an int literal and therefore must be in the range defined by int.
If you want to write a long literal, then you must make that explicit by appending the L (or lower case l, but I highly suggest you always use the upper-case variant, because it's much easier to read and harder to mistake for a 1).
Note that a similar problem occurs with float (postfix F/f) and double (postfix D/d).
Side note: you'll realize that there are no byte or short literals and you can still assign values (usually int literals) to byte and short variables: that's possible due to special rules in § 5.2 about conversions in an Assignment Contexts: they allow assignment of constant expressions of a larger type to byte, short, char or int if the values are within the types range.
Try doing 9223372036854775807L. The L at the end tells Java that 9223372036854775807 is a long.
I had this problem in the past and I fixed that by writing the value in the scientific form.
for example:
double val = 9e300;
long ak = 34778754226788444L/l;
Both use but at a time only one use uppercase L or lowercase l.
Why use L/l? Because long is a part of integral datatype.

Understanding Java data types

1) Why is the following assignment not allowed:
byte b = 0b11111111; // 8 bits or 1 byte
but this assignment is allowed:
int i = 0b11111111111111111111111111111111; //32 bits or 4 bytes
Both types are signed, and I would expect b and i were -1.
2) Why doesn't the Integer MIN_VALUE have a sign?
public static final int MIN_VALUE = 0x80000000;
but the Byte MIN_VALUE does have a sign?
public static final byte MIN_VALUE = -128;
Question 1)
This is because 0b11111111 is an int literal, whose value is 255. This value doesn't fit into a byte. See http://docs.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html for more details on this.
Question 2)
When we write binary or hexadecimal literals, we never put a sign. The literal 0x80000000 is actually a negative value, even though we don't write it as such.
There's no really good reason why the makers of the JDK chose to use a decimal literal for -128 but a hexadecimal literal for 0x80000000; except that in each case, it's probably a whole lot clearer that way what is intended.
All integer literals have type int (unless suffixed by an L or l). Thus, in the first case, you're storing an int into a byte. A narrowing conversion like this is not allowed without a cast, except that if the right side is a constant, it's allowed if the value is in range, which is -128 to 127. 0b11111111 is 255, though, which is not in range.
As for why int i = 0b11111111111111111111111111111111 is allowed: it's pretty much "because the JLS says so". In fact, that specific example appears in JLS 3.10.1. There's a rule that decimal literals of type int cannot exceed 214743647 (except in the specific case -2147483648), but there's no rule about binary literals except that they have to fit into 32 bits.
As I mentioned in a comment, the second question is really a question about the style preference of the programmers who wrote the code, and it's impossible to answer.

Java - derby - unsigned int

I would like that one of my columns in a specific table would not get negative numbers.
Is there a way to declare an unsigned int in derby DB ?
Q: Is there a way to declare a column "unsigned int" in a Derby DB table?
A: I believe answer is "No":
http://db.apache.org/derby/docs/10.0/manuals/reference/sqlj124.html
http://db.apache.org/derby/docs/10.0/manuals/reference/sqlj124.html
... HOWEVER ...
You should easily be able to "CAST" the stored value in any query:
The answer is no. Java (unfortunately) has no support for unsigned arithmetics.
But you can still use Java's int and make your own methods to do unsigned arithmetic, like this. Even better is to create an UnsignedInteger class and let it handle all that arithmetic.
I don't know if it's worth it though. You can just use long as jtahlborn suggests.
Java does NOT support the type unsigned int, as opposed to C or C++.
On the other hand, there is a simple way to circumvent this limitation by using:
An intermediate long variable/literal
A cast to (int)
First, let us note that both signed and unsigned int have the same number of bits; they are both 32 bits in size.
The main difference is, that for signed integers the MSB (Most Significant Bit) or bit 0 is used to indicate that the actual integer is negative or positive.
If this bit is set to 1 the integer is negative, if it is set to 0, the integer is negative. So, you will end up with 31 bits for the value of the integer, and 1 bit for the sign.
For unsigned integers, all the 32 bits are used to represent the value of the integer. You can now have larger numbers.
The signed integers range from -2^31 to (2^31 - 1)
The unsigned integers range from 0 to (2^32 - 1)
To show the size limitation issue, try to compile the following snippet:
public static void main (String[] args){
int i = 2_147_483_648;//This line will generate a compiler error
}
}
The compiler will complain saying integer number too large.
Let us see how we can circumvent this and still store this number in a Java integer, and retrieve it back.
The idea behind the proposed solution stems from the fact that a series of bits is interpreted to mean something. It could be a representation of an image, a Java object, a C struct, a character, etc.
You "interpret" the series of bits based on what you "expect" that series of bits to represent. If you are expecting a character, you might be looking to match the series against an ASCII table. If you are expecting an image, you might be looking to decode a JPEG.
Now, and coming back to integers, if you are looking for signed integers you will interpret the MSB as the sign bit. If you are looking for unsigned integers you will interpret the MSB as part of the value.
To give an example, let us assume that you have the following series of 32 bits:
in hex 0x8000_0000 or in binary 0b1000_0000_0000_0000_0000_0000_0000_0000
The MSB is set to 1 all other bits are 0.
If you are looking for/expecting a signed integer these 32 bits would be interpreted as the representation of the negative decimal number -2_147_483_648
If you are looking for/expecting an unsigned integer these same 32 bits would be interpreted as the representation of the positive decimal number 2_147_483_648
Hence, the solution would be to store the values in a signed 32-bit integer and interpret them as an unsigned 32-bit integer.
Here is how we will modify the previous snippet and save 2_147_483_648 into an integer value and be able to print it correctly.
To do so, we will:
First, use a long intermediate datatype/value
Then cast that value to int to save it
Finally, mask/ignore & the extra bits and display it
public static void main (String[] args){
//1. cast a 64-bit long value that fits into a 32-bit int
int i = (int)2_147_483_648L;
//2. Mask the extra long bits
System.out.println(i & 0x0000_0000_FFFF_FFFFL);
}
}
The long variable can hold 64 bits, and its MSB, or sign bit, is not affected by its first 32 bits. You will notice a bitwise operation happening here:
i & 0x0000_0000_FFFF_FFFFL
This is telling the compiler to ignore, or mask, all the bits that are beyond the first 32 bits we are interested in. Our integer is 32-bit.
If you want to do some arithmetic operation on the int value before saving it, you could resort again to a long intermediate variable.
Here is how, and this will be the proposed solution:
public static void main (String[] args){
int i = (int)2_147_483_648L;
int j = 1_000_000;
long tempL = i + j;//Use a temp long to perform the operations
i = (int)tempL; //We save back into i and store in a DB for example
//Now we use the saved value to display it, for example
System.out.println(i & 0x0000_0000_FFFF_FFFFL);
}
}
Good luck and hope the above helps!

Declaring an unsigned int in Java

Is there a way to declare an unsigned int in Java?
Or the question may be framed as this as well:
What is the Java equivalent of unsigned?
Just to tell you the context I was looking at Java's implementation of String.hashcode(). I wanted to test the possibility of collision if the integer were 32 unsigned int.
Java does not have a datatype for unsigned integers.
You can define a long instead of an int if you need to store large values.
You can also use a signed integer as if it were unsigned. The benefit of two's complement representation is that most operations (such as addition, subtraction, multiplication, and left shift) are identical on a binary level for signed and unsigned integers. A few operations (division, right shift, comparison, and casting), however, are different. As of Java SE 8, new methods in the Integer class allow you to fully use the int data type to perform unsigned arithmetic:
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^32-1. Use the Integer class to use int data type as an unsigned integer. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
Note that int variables are still signed when declared but unsigned arithmetic is now possible by using those methods in the Integer class.
Whether a value in an int is signed or unsigned depends on how the bits are interpreted - Java interprets bits as a signed value (it doesn't have unsigned primitives).
If you have an int that you want to interpret as an unsigned value (e.g. you read an int from a DataInputStream that you know should be interpreted as an unsigned value) then you can do the following trick.
int fourBytesIJustRead = someObject.getInt();
long unsignedValue = fourBytesIJustRead & 0xffffffffL;
Note, that it is important that the hex literal is a long literal, not an int literal - hence the 'L' at the end.
We needed unsigned numbers to model MySQL's unsigned TINYINT, SMALLINT, INT, BIGINT in jOOQ, which is why we have created jOOU, a minimalistic library offering wrapper types for unsigned integer numbers in Java. Example:
import static org.joou.Unsigned.*;
// and then...
UByte b = ubyte(1);
UShort s = ushort(1);
UInteger i = uint(1);
ULong l = ulong(1);
All of these types extend java.lang.Number and can be converted into higher-order primitive types and BigInteger. Hope this helps.
(Disclaimer: I work for the company behind these libraries)
For unsigned numbers you can use these classes from Guava library:
UnsignedInteger
UnsignedLong
They support various operations:
plus
minus
times
mod
dividedBy
The thing that seems missing at the moment are byte shift operators. If you need those you can use BigInteger from Java.
Perhaps this is what you meant?
long getUnsigned(int signed) {
return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
}
getUnsigned(0) → 0
getUnsigned(1) → 1
getUnsigned(Integer.MAX_VALUE) → 2147483647
getUnsigned(Integer.MIN_VALUE) → 2147483648
getUnsigned(Integer.MIN_VALUE + 1) → 2147483649
Use char for 16 bit unsigned integers.
There are good answers here, but I don’t see any demonstrations of bitwise operations. Like Visser (the currently accepted answer) says, Java signs integers by default (Java 8 has unsigned integers, but I have never used them). Without further ado, let‘s do it...
RFC 868 Example
What happens if you need to write an unsigned integer to IO? Practical example is when you want to output the time according to RFC 868. This requires a 32-bit, big-endian, unsigned integer that encodes the number of seconds since 12:00 A.M. January 1, 1900. How would you encode this?
Make your own unsigned 32-bit integer like this:
Declare a byte array of 4 bytes (32 bits)
Byte my32BitUnsignedInteger[] = new Byte[4] // represents the time (s)
This initializes the array, see Are byte arrays initialised to zero in Java?. Now you have to fill each byte in the array with information in the big-endian order (or little-endian if you want to wreck havoc). Assuming you have a long containing the time (long integers are 64 bits long in Java) called secondsSince1900 (Which only utilizes the first 32 bits worth, and you‘ve handled the fact that Date references 12:00 A.M. January 1, 1970), then you can use the logical AND to extract bits from it and shift those bits into positions (digits) that will not be ignored when coersed into a Byte, and in big-endian order.
my32BitUnsignedInteger[0] = (byte) ((secondsSince1900 & 0x00000000FF000000L) >> 24); // first byte of array contains highest significant bits, then shift these extracted FF bits to first two positions in preparation for coersion to Byte (which only adopts the first 8 bits)
my32BitUnsignedInteger[1] = (byte) ((secondsSince1900 & 0x0000000000FF0000L) >> 16);
my32BitUnsignedInteger[2] = (byte) ((secondsSince1900 & 0x000000000000FF00L) >> 8);
my32BitUnsignedInteger[3] = (byte) ((secondsSince1900 & 0x00000000000000FFL); // no shift needed
Our my32BitUnsignedInteger is now equivalent to an unsigned 32-bit, big-endian integer that adheres to the RCF 868 standard. Yes, the long datatype is signed, but we ignored that fact, because we assumed that the secondsSince1900 only used the lower 32 bits). Because of coersing the long into a byte, all bits higher than 2^7 (first two digits in hex) will be ignored.
Source referenced: Java Network Programming, 4th Edition.
It seems that you can handle the signing problem by doing a "logical AND" on the values before you use them:
Example (Value of byte[] header[0] is 0x86 ):
System.out.println("Integer "+(int)header[0]+" = "+((int)header[0]&0xff));
Result:
Integer -122 = 134
Just made this piece of code, wich converts "this.altura" from negative to positive number. Hope this helps someone in need
if(this.altura < 0){
String aux = Integer.toString(this.altura);
char aux2[] = aux.toCharArray();
aux = "";
for(int con = 1; con < aux2.length; con++){
aux += aux2[con];
}
this.altura = Integer.parseInt(aux);
System.out.println("New Value: " + this.altura);
}
You can use the Math.abs(number) function. It returns a positive number.

Categories