java.lang.Double.longBitsToDouble function in JavaScript - java

I have a BinaryStream class in JavasScipt that reads bytes from an array downloaded via XMLHHttpRequest and has the function next() which returns an unsigned byte (technically an integer). I need to read a double from the stream which is basically the same as DataStream.readDouble() from Java which uses the method Double.longBitsToDouble(long). I can't figure out how the longBitsToDouble method works.
This is the the code I have:
var bits = stream.nextLong();
if (bits == 0x7ff0000000000000)
this.variables = [Infinity];
else if (bits == 0xfff0000000000000)
this.variables = [-Infinity];
else if (bits >= 0x7ff0000000000001 && bits <= 0x7fffffffffffffff || bits >= 0xfff0000000000001 && bits <= 0xfff0000000000001)
this.variables = [NaN];
else
{
var s = ((bits >> 63) == 0) ? 1 : -1;
var e = ((bits >> 52) & 0x7ff);
this.variables = [(e == 0) ? (bits & 0xfffffffffffff) << 1 : (bits & 0xfffffffffffff) | 0x10000000000000];
// This must be incorrect because it returns a number many times higher than it should
}
console.log(this.variables[0]);

I found a JavaScript library that can encode and decode many different types of numbers from an array of bytes here.

http://code.google.com/p/quake2-gwt-port/source/browse/src/com/google/gwt/corp/compatibility/Numbers.java has an implementation of floatToLongBits. I'd start with that. You should be able to just tweak the mantissa mask and size and the exponent mask and size.
Joel Webber (of GWT advises caution):
The Quake code has only ever been tested on WebKit (Nitro & V8), so I would
check it carefully before using. float/doubleToLongBits() in Javascript is a
truly, truly foul piece of work that is horrifically inefficient. Use with
caution.

Related

Why the calculation of hash in HashMap(JDK1.8) don't need to consider the negative hashCode as ConcurrentHashMap does?

In HashMap: (h = key.hashCode()) ^ (h >>> 16);
In ConcurrentHashMap: (h ^ (h >>> 16)) & HASH_BITS;
where HASH_BITS is 0x7fffffff, by & HASH_BITS it can always be a positive number.
Why the calculation of hash in HashMap(JDK1.8) don't need to consider the negative hashCode as ConcurrentHashMap does?
Ultimately, the case where the hash is negative (after spreading) does need to be considered in the HashMap case as well. It is just that this happens later in the code.
For example, in getNode (Java 8) you find this:
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
Since tab.length is a power of 2, tab.length - 1 is a suitable bitmask for reducing hash to a subscript for the array.
You can rest assured that in every implementation of HashMap or ConcurrentHashMap there is some code that reduces the hash code to a number that is suitable for use as a subscript. It will be there ... somewhere.
But also ... don't expect the code of these classes to be easy to read. All of the collection classes have been reworked / tuned multiple times get the best possible (average) performance over a wide range of test cases.
Actually it handles negative index calculations. It's not evident at first looking but there are calculations in some places while accessing the elements(key or value).
int index = (n - 1) & hash, in which n is length of the table
It simply handles negative indexing.
AFAIK, HashMap always uses arrays sized to a power of 2 (e.g. 16, 32, 64, etc.).
Let's assume we have capacity of 256(0x100) which is 2^8.
After subtraction 1, we get 256 - 1 = 255 which is 0x100 - 0x1 = 0xFF
The subtraction gives rise to get the proper bucket index between 0 to length-1 with exact bit mask needed to bitwise-and with the hash.
256 - 1 = 255
0x100 - 0x1 = 0xFF
A hash of 260 (0x104) gets bitwise-anded with 0xFF to yield a bucket number of 4.
A hash of 257 (0x101) gets bitwise-anded with 0xFF to yield a bucket number of 1.

Finding out number of bits that have changed (bitwise operator)

I have a bit string that is generated based on user input. I also have another bit string that I use to perform bitwise & with the generated bit string. What I would like to know is how to find out how many bits of the generated bit string has changed from the & operation. So let say if I have 10000101 as generated bit string and 00101111 as a second bit string I use for & operation. The output of the process should be 1 since only the first bit of the generate bit string has changed. How do I do that?
What you are looking for is bitwise XOR (exclusively OR), or a^b:
10000101 ^ 00101111 → 10101010
Is is logically equivalent to (~a&b) | (a&~b)
You need to XOR the result with the original to identify which bits were changed:
changedBits = (userInput & generatedInput) ^ userInput
Then, you need to calculate the Hamming Weight of the changedBits value:
int hammingWeight(int i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
return (((i + (i >>> 4)) & 0x0F0F0F0F) * 0x01010101) >>> 24;
}
int numberOfChangedBits = hammingWeight(changedBits);
Adjust as needed depending on how many bits your inputs are.

How does the call to the hashing algorithm work, particularly the use of bit shifting 0xff?

The following code snippet, sourced from Core Java Vol 2 (7th Ed), shows how to create an SHA1 and an MD5 fingerprint using Java.
It turns out that the only function that works is when I load the cleartext from a textfile.
How does MessageDigestFrame.computeDigest() work out the fingerprint, and, particularly the use of the bit shifting pattern (Line 171 - 172)?
public void computeDigest(byte[] b)
{
currentAlgorithm.reset();
currentAlgorithm.update(b);
byte[] hash = currentAlgorithm.digest();
String d = "";
for (int i = 0; i < hash.length; i++)
{
int v = hash[i] & 0xFF;
if (v < 16) d += "0";
d += Integer.toString(v, 16).toUpperCase() + " ";
}
digest.setText(d);
}
The method should work fine whatever you give it - if you're getting the wrong results, I suspect you're loading the file incorrectly. Please show that code, and we can help you work out what's going wrong.
In terms of the code, this line:
int v = hash[i] & 0xFF;
is basically used to treat a byte as unsigned. Bytes are signed in Java - an acknowledged design mistake in the language - but we want to print out the hex value as if it were an unsigned integer. The bitwise AND with just the bottom 8 bits effectively converts it to the integer value of the byte treated as unsigned.
(There are better ways to convert a byte array to a hex string, but that's a separate matter.)
It is not bit shifting, it is bit masking. hash[i] is a byte. When it is widened to integer you need to mask off the higher integer bits because of possible sign extension.
byte b = (byte)0xEF;
System.out.println("No masking: " + (int)b);
System.out.println("Masking: " + (int)(b & 0xFF));
This snipped:
int v = hash[i] & 0xFF;
if (v < 16) d += "0";
d += Integer.toString(v, 16).toUpperCase() + " ";
First you set all but the lowest 8 bits of v to 0 (because 0xFF is 11111111 in binary).
Then if the resulting number is only one digit in hex (< 16) you add a leading "0".
Finally convert the result to hex and add it to the string.

CRC-CCITT validation in java (android)

Hi
I have some data being received over a bluetooth connection.
The data has a 16-bit CRC 16-CCITT block which I want to use in order to verify that the data was transferred successfully and without error.
Is there any built in method in java or android that can help me or do I need to implement it myself? Will I need to encode the data and compare? I have a code snippet for doing that which I found online, but I'm not sure it is correct or efficient.
It is found at: http://introcs.cs.princeton.edu/java/51data/CRC16CCITT.java.html and the code is:
int crc = 0xFFFF; // initial value
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
// byte[] testBytes = "123456789".getBytes("ASCII");
byte[] bytes = args[0].getBytes();
for (byte b : bytes) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7-i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
}
}
crc &= 0xffff;
System.out.println("CRC16-CCITT = " + Integer.toHexString(crc));
I also saw that Java has an implementation of crc32 at http://download.oracle.com/javase/1.4.2/docs/api/java/util/zip/CRC32.html. Is that something I can use here?
Thanks.
It is very inefficient. There is a table-driven version around the Internet written originally in C in the 1980s that runs at least 8 times as fast. The Wikipedia article appears to provide some links.

How do I compare two longs as unsigned in Java?

I'm storing bit patterns of unsigned 64-bit numbers in a long variable and want to calculate the distance between two of them on the unsigned range. Because Java interprets long as a two's complement signed integer, I can't just do a - b, as the following example shows:
// on the unsigned range, these numbers would be adjacent
long a = 0x7fffffffffffffffL;
long b = 0x8000000000000000L;
// but as two's complement (or any representation that
// stores the sign in the first bit), they aren't
assert b - a == 1;
What's the correct way to do this?
Starting with Java 8, the comparison of long as unsigned integers can be done via Long.compareUnsigned(x, y).
Here is a simple backport for Java 7 and earlier:
public static int compareUnsigned(long x, long y) {
return Long.compare(x + Long.MIN_VALUE, y + Long.MIN_VALUE);
}
As the arithmetic wraps round, it works out the same for the case you give. If you interpret the result as an unsigned value, it will be true for all cases - you're just changing the interpretation of the bit pattern, it's still a set homomorphic to Ζ264.
If you're dealing with addition and subtraction, it doesn't matter whether you're using signed or unsigned types, as long as the arguments are both signed or both unsigned. If you need to compare a and b, compare a-b to 0.
Works for me:
long a = 0x7fffffffffffffffL;
long b = 0x8000000000000000L;
b - a = (long) 1
a - b = (long) -1
I used this solution:
if (longA == longB) return 0;
return (longA < longB) ^ (longA < 0) ^ (longB< 0) ? 1 : -1;
All credits go to this website
As previously mentioned, you won't have a problem with subtraction, so if that is all you are trying to do, then don't worry.
But, by your example, addition will overflow, and none of the relational operators will work properly. If this is a concern then you can write your own relational ops, or use a better box type than Long.
Solutions:
1. Use BigInteger instead of Long. BigInteger was created for doing calculations with large numbers and can easily support 128bit calculations.
Write your own relational operations and exclude the used of addition or multiplication as a possibility. Writing your own relational operator is really not that hard. First you compare the most significant bit. If the most significant bit is the same for both numbers, you can mask it by doing a bitwise and (&) with 0X7FFFFFFFFFFFFFFF and then compare the masked values.
I use the following code:
static boolean unsignedLessThan(long left, long right) {
return (left < right) ^ (left < 0) ^ (right < 0);
}
(based on example by Tamutnefret)
http://www.darksleep.com/player/JavaAndUnsignedTypes.html
Obviously you need deal with bits.
static boolean compare(long a, long b)
{
if(( a & (Long.MAX_VALUE + 1)) != 0)
return ( b & (Long.MAX_VALUE + 1) ) != 0
? (a < b) //same sign
: true; //a is greater b
else
return ( b & (Long.MAX_VALUE + 1) ) != 0
? false //b is greater a
: a < b; //same sign
}
Or you can do half and half like this,
public static long unsignedDiff(long a, long b) {
long mask = 0xFFFFFFFFL;
return (( ((a >> 32) & mask) - ((b >> 32) & mask) ) << 32) +
+ ((a & mask) - (b & mask));
}

Categories

Resources