Print double as raw hex? - java

I'm interested in printing a double as raw hex. I don't want the mantissa and exponent interpreted.
Is there a print function in Java to accomplish it?
If not, how does one extract raw octets from a double in Java?

Use Double.doubleToLongBits() or Double.doubleToRawLongBits().

First, get the bits as long, using Double.doubleToLongBits() or Double.doubleToRawLongBits().
However if you would like to print the bits then and if you have Java 8, I would recommend converting your long to String using the new unsigned API, possibly with base 16 or 2.
double number = Math.E;
long bits = Double.doubleToRawLongBits(number);
System.out.println(Long.toUnsignedString(bits, 16)); // 4005bf0a8b145769

Related

Calculating decimal representation of an integer in Java

This might seem really naive but I am not sure what is the decimal representation of an integer?
Can you provide some code in Java to convert an integer to its decimal representation?
Thanks!
My answer would have been Integer.toString(value).
Done! I have now "calculated" the decimal representation of an integer (int value).
As the javadoc says:
The argument is converted to signed decimal representation and returned as a string.
Of course, they probably wanted you to write the code that implements that method, rather than using the library method.
You can use things like this :
Integer i = 10;
Double iDecimal = new Double(i);
System.out.println(iDecimal); //would print 10.0 i.e. decimal

Can one force String.valueOf() to return unsigned value in Java? [duplicate]

This question already has answers here:
Can we make unsigned byte in Java
(17 answers)
Closed 9 years ago.
I have a byte array:
byte[] a = new byte[3];
which I have added some bytes. For this example, let's say 3, 4, and 210.
I would like to print this string of bytes to look like 3 4 210, but instead I get 3 4 -46
I am using String.valueOf(a[i]) to do my conversion. Is there any way to force this conversion to give unsigned values?
Thanks in advance,
EDIT: Thanks to the various feedback on this question. I had not realized Java Bytes were signed values by default, and so was suspecting the String.valueOf() method as being the issue. It turns out just simply using
String.valueOf(a[i]&0xFF)
takes care of the signed formatting issue.
Again, thank you for your feedback!
Guava provides a UnsignedBytes class that can make that conversion. The static toString(byte) method
Returns a string representation of x, where x is treated as unsigned.
For example
System.out.println(UnsignedBytes.toString(a[i]));
where a[i] = -46 would print
210
Internally, all this does is call
public static int toInt(byte value) {
return value & UNSIGNED_MASK; // UNSIGNED_MASK = 0xFF
}
and convert the int to a String which it returns.
For an explanation
With
someByte & 0xFF
since OxFF is an integer literal, the someByte value is widened to an int. Let's take for example the value -46. Its binary representation is
11111111111111111111111111010010
The binary representation of 0xFF is
11111111 // ie 255
if you and & the two
11111111111111111111111111010010
00000000000000000000000011111111
--------------------------------
00000000000000000000000011010010
which is equal to
210
Basically you only keep the lower 8 bits of the int.
Java byte data type range is minimum value of -128 and a maximum value of 127 (inclusive). String.valueOf(a[i]) doesn't do this conversion. Use int type instead.
byte
byte range limit is within -128 to 127,
so for 210 it gives -46. so convert it using int type
You've run into Java's famous problem of bytes treated as signed even though most of the real world prefers these unsigned. Try this:
int[] signedArr = new int[a.length];
for (int i=0; i<a.length; ++i) {
signedArr[i] = a[i] & 0xff;
}
Then you can work with signedArr.

Need an alternative for .parse function

I am currently dealing with numbers with different bases. I am using the function Long.parseLong to convert a number from base int to its decimal value:
Long.parseLong("A", 16) to convert A which is a hexadecimal to its decimal value 10. I then use Long.toString(10, 16) to convert it back to A.
The problem now is that one of the entries in the problem set is "AAAAAAAAAAAAAAAAAAA" and when I use the Long.parseLong(); function, it returns an error because the size of the conversion can't fit to a Long. I tried to use Float, but I'm afraid that there is no Float.parseFloat(String, int) with the int as its radix.
Is there an alternative which I can use?
BigInteger also doesn't have any parse function with the radix.
Any help will be much appreciated.
BigInteger has a constructor, which does radix conversion for you:
BigInteger num = new BigInteger("AAAAAAAAAAAAAAAAAAA", 16);
If you wish to convert back to hexadecimal, you can use toString:
String hex = num.toString(16);

Converting US-ASCII encoded byte to integer and back

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"));

How to Parse Negative Long in Hex in Java

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.)

Categories

Resources