I have a Objective C code,which I have to translate in Java,but I have a little problem with converting one line. In Objective C code I have : UInt64 iz = strtoull(s,&s1,16);. I was searching over the internet abotu strtoull and I find this information for it :
strtoul will convert a string to an unsigned long integer. An
important feature of this function is the ability to accept data in
various number bases and convert to decimal.
The first argument must not contain a + or -. The second argument
(char **endptr) seems to be a waste of space! If it is set to NULL,
STRTOL seems to work its way down the string until it finds an invalid
character and then stops. All valid chars read are then converted if
the string starts with an invalid character the function returns ZERO
(0).
The Third argument (base) can have a value of 0 or 2-32.
0 - strtol will attempt to pick the base. Only Dec, Oct Hex supported.
2-31 - The base to use.
I tried to find a way to do this in Java.As a made some researches I got this :
long l=Long.parseLong(md5Hash, 16);
And my question is,is parseLong equivalent to strtoull and can I use it for my application? If not can you suggest me what can I use?
Thanks in advance!
You can't because long is signed in Java. If you need unsigned integers for the full value range of 64 Bit then you have to use the BigInteger class.
Long.parseLong is the usual way of parsing a string into a long. But be aware that Java does not have unsigned types.
It is equivalent but keep in mind that long in Java is not unsigned. Therefore, a Java long is in [-2^63, 2^63 - 1].
use
BigInteger(String val, int radix)
Related
Normally whilst programming in LibGDX, passing the Color class an integer of a hex value works just fine:
new Color(0xeaeaeaff);
But doing this from Clojure...
(Color. 0xeaeaeaff)
... generates the error java.lang.IllegalArgumentException: Value out of range for int: 3,941,264,128. Sure that value does look out of range, very much so. But when I normally do it from Java, there is no problem at all?
The Clojure value is defined like so:
(def color 0xff00ffff)
Why does this happen?
The easiest way to get the same value that Java would give you, with the same literal as the input, is to use unchecked-int. It will return a negative (overflowed) number, just like the original, rather than giving an out of bounds error.
+user=> (unchecked-int 0xeaeaeaff)
-353703169
0xeaeaeaff in Java represents a negative number: -353703169 and causes overflow in Clojure (Java is just overflowing it to a negative number).
In your case 0xeaeaeaff in Java is equal to -353703169 in base 10. You can write it just as -353703169 in Clojure, or in base 16 as -16r15151501.
You can use unchecked-int as pointed out by noisesmith.
In Java, using literal notation for hexadecimal numbers produces ints, so 0xeaeaeaff is an int with the value -353703169, because it exceeds the max value for ints, overflows and becomes a negative int.
In Clojure 0xeaeaeaff produces a long with the value 3941264127.
The class com.badlogic.gdx.graphics.Color of LibGDX has a constructor that expects an int but not one that expects a long, which you are passing to it in the Clojure case, hence the exception: java.lang.IllegalArgumentException: Value out of range for int: 3,941,264,128.
You could just pass -353703169 to the constructor or use (Integer/parseUnsignedInt "eaeaeaff" 16) like Piotrek suggested, as it would probably be more convinient, possibly through a wrapper function:
(defn hex->int [arg]
(Integer/parseUnsignedInt arg 16))
I have a byte array that can be of size 2,3 or 4. I need to convert this to the correct integer value. I also need to do this in reverse, i.e an 2,3 or 4 character integer to a byte array.
e.g., raw hex bytes are : 54 and 49. The decoded string US-ASCII value is 61. So the integer answer needs to be 61.
I have read all the conversion questions on stackoverflow etc that I could find, but they all give the completely wrong answer, I dont know whether it could be the encoding?
If I do new String(lne,"US-ASCII"), where lne is my byte array, I get the correct 61. But when doing this ((int)lne[0] << 8) | ((int)lne[1] & 0xFF), I get the complete wrong answer.
This may be a silly mistake or I completely don't understand the number representation schemes in Java and the encoding/decoding idea.
Any help would be appreciated.
NOTE: I know I can just parse the String to integer, but I would like to know if there is a way to use fast operations like shifting and binary arithmetic instead?
Here's a thought on how to use fast operations like byte shifting and decimal arithmetic to speed this up. Assuming you have the current code:
byte[] token; // bytes representing a bunch of ascii numbers
int n = Integer.parseInt(new String(token)); // current approach
Then you could instead replace that last line and do the following (assuming no negative numbers, no foreign langauge characters, etc.):
int n = 0;
for (byte b : token)
n = 10*n + (b-'0');
Out of interest, this resulted in roughly a 28% speedup for me on a massive data set. I think this is due to not having to allocate new String objects and then trash them after each parseInt call.
You need two conversion steps. First, convert your ascii bytes to a string. That's what new String(lne,"us-ascii") does for you. Then, convert the string representation of the number to an actual number. For that you use something like Integer.parseInt(theString) -- remember to handle NumberFormatException.
As you say, new String(lne,"US-ASCII") will give you the correct string. To convert your String to an integer, use int myInt = Integer.parseInt(new String(lne,"US-ASCII"));
We have a J2ME application that needs to read hex numbers. The application is already too big for some phones so We try not to include any other codec or write our own function to do this.
All the numbers are 64-bit signed integers in hex, when we use Long.ParseLong(hex, 16), it handles positive numbers correctly but it throws exception on negative numbers,
long l = Long.parseLong("FFFFFFFFFFFFFFFF", 16);
How can we get -1 from that hex string using classes provided in Java itself?
Some people may suggest we should write our hex as -1 as Java expected. Sorry, the format is fixed by the protocol and we can't change it.
Your problem is that parseLong() does not handle two's complement - it expects the sign to be present in the form of a '-'.
If you're developing for the CDC profile, you can simple use
long l = new BigInteger("FFFFFFFFFFFFFFFF", 16).longValue()
But the CLDC profile doesn't have that class. There, the easiest way to do what you need is probably to split up the long, parse it in two halves and recombine them. This works:
long msb = Long.parseLong("FFFFFFFF", 16);
long lsb = Long.parseLong("FFFFFFFF", 16);
long result = msb<<32 | lsb;
UPDATE
As of Java 8, you can use parseUnsignedLong():
long l = Long.parseUnsignedLong("FFFFFFFFFFFFFFFF", 16);
Parse it in chunks.
long l = (Long.parseLong("FFFFFFFFF",16)<<32) | Long.parseLong("FFFFFFFF",16);
Worse case scenario, you could check to see if the string is 16 characters that begins with an 8-F, and if so, change that to the equivalent character w/o the most significant bit set (i.e. subtract 8 from that digit), parse the result, and add the parsed value to the lower bound of a signed long? (Essentially just doing the 2's complement yourself.)
It's quite straight forward in java to parse number from String, i.e. with Integer.parseInt(s) if string in the format 'n' or '-n', but unfortunately it fails to parse string in the format of '+n'.
So what is the most effective/elegant way to parse number from string in java if it contains positive or negative prefix: '+n' or '-n' ?
Integer.parseInt(s.replace("+", ""));
In truth there are many gotchas using Integer to parse numbers like that, in that Integer has very specific bounds of size and format ("1,000,000.00") isn't parsing that way, but I'm taking your question as Integer.parseInt meets your needs just fine, you just have to deal with a + in your data.
Just FYI, this has been fixed in Java 7.
from, Java SE8 for the Really Impatient
Prior to JDK 1.7, what was the result of the following code segment?
double x = Double.parseDouble("+1.0");
int n = Integer.parseInt("+1");
Pat yourself on the back if you knew the
answer: +1.0 has always been a valid floating-point number, but
until Java 7, +1 was not a valid integer. This has now been fixed
for all the various methods that construct int, long, short, byte,
and BigInteger values from strings. There are more of them than you
may think. In addition to parse (Int|Long|Short|Byte), there are
decode methods that work with hexadecimal and octal inputs, and
valueOf methods that yield wrapper objects. The BigInteger(String)
constructor is also updated.
In Java, there is no such thing as an unsigned byte.
Working with some low level code, occasionally you need to work with bytes that have unsigned values greater than 128, which causes Java to interpret them as a negative number due to the MSB being used for sign.
What's a good way to work around this? (Saying don't use Java is not an option)
It is actually possible to get rid of the if statement and the addition if you do it like this.
byte[] foobar = ..;
int value = (foobar[10] & 0xff);
This way Java doesn't interpret the byte as a negative number and flip the sign bit on the integer also.
When reading any single value from the array copy it into something like a short or an int and manually convert the negative number into the positive value it should be.
byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value
You can do a similar conversion when writing into the array.
Using ints is generally better than using shorts because java uses 32-bit values internally anyway (Even for bytes, unless in an array) so using ints will avoid unnecessary conversion to/from short values in the bytecode.
Probably your best bet is to use an integer rather than a byte. It has the room to allow for numbers greater than 128 without the overhead of having to create a special object to replace byte.
This is also suggested by people smarter than me (everybody)
http://www.darksleep.com/player/JavaAndUnsignedTypes.html
http://www.jguru.com/faq/view.jsp?EID=13647
The best way to do bit manipulation/unsigned bytes is through using ints. Even though they are signed they have plenty of spare bits (32 total) to treat as an unsigned byte. Also, all of the mathematical operators will convert smaller fixed precision numbers to int. Example:
short a = 1s;
short b = 2s;
int c = a + b; // the result is up-converted
short small = (short)c; // must cast to get it back to short
Because of this it is best to just stick with integer and mask it to get the bits that you are interested in. Example:
int a = 32;
int b = 128;
int foo = (a + b) | 255;
Here is some more info on Java primitive types http://mindprod.com/jgloss/primitive.html
One last trivial note, there is one unsigned fixed precision number in Java. That is the char primitive.
I know this is a very late response, but I came across this thread when trying to do the exact same thing. The issue is simply trying to determine if a Java byte is >127.
The simple solution is:
if((val & (byte)0x80) != 0) { ... }
If the real issue is >128 instead, just adding another condition to that if-statement will do the trick.
I guess you could just use a short to store them. Not very efficient, but really the only option besides some herculean effort that I have seen.