In Java Double.doubleToLongBits() is useful for implementing hashCode() methods.
I'm trying to do the same in C++ and write my own doubleToRawLongBits() method, as after trawling through Google I can't find a suitable implementation.
I can get the signif and exponent from std::frexp(numbr,&exp) and can determine the sign but can't figure out the use of the bitwise operators to get the Java equivalent.
For example, Java's Double.doubleToLongBits() returns the following for the double 3.94:
4616054510065937285
Thanks for any help.
Graham
Below is the documentation copied and pasted from Double.doubleToRawLongBits()
===Java Double.doubleToRawLongBits() description===
/**
* Returns a representation of the specified floating-point value
* according to the IEEE 754 floating-point "double
* format" bit layout, preserving Not-a-Number (NaN) values.
* <p>
* Bit 63 (the bit that is selected by the mask
* <code>0x8000000000000000L</code>) represents the sign of the
* floating-point number. Bits
* 62-52 (the bits that are selected by the mask
* <code>0x7ff0000000000000L</code>) represent the exponent. Bits 51-0
* (the bits that are selected by the mask
* <code>0x000fffffffffffffL</code>) represent the significand
* (sometimes called the mantissa) of the floating-point number.
* <p>
* If the argument is positive infinity, the result is
* <code>0x7ff0000000000000L</code>.
* <p>
* If the argument is negative infinity, the result is
* <code>0xfff0000000000000L</code>.
* <p>
* If the argument is NaN, the result is the <code>long</code>
* integer representing the actual NaN value. Unlike the
* <code>doubleToLongBits</code> method,
* <code>doubleToRawLongBits</code> does not collapse all the bit
* patterns encoding a NaN to a single "canonical" NaN
* value.
* <p>
* In all cases, the result is a <code>long</code> integer that,
* when given to the {#link #longBitsToDouble(long)} method, will
* produce a floating-point value the same as the argument to
* <code>doubleToRawLongBits</code>.
*
* #param value a <code>double</code> precision floating-point number.
* #return the bits that represent the floating-point number.
* #since 1.3
*/
public static native long doubleToRawLongBits(double value);
A simple cast will do:
double d = 0.5;
const unsigned char * buf = reinterpret_cast<const unsigned char *>(&d);
for (unsigned int i = 0; i != sizeof(double); ++i)
std::printf("The byte at position %u is 0x%02X.\n", i, buf[i]);
Where the sign bit and exponent bits are depends on your platform and the endianness. If your floats are IEE754, if the sign and exponent are at the front and if CHAR_BIT == 8, you can try this:
const bool sign = buf[0] & 0x80;
const int exponent = ((buf[0] & 0x7F) << 4) + (buf[1] >> 4) - 1023;
(In C, say (const unsigned char *)(&d) for the cast.)
Update: To create an integer with the same bits, you have to make the integer first and then copy:
unsigned long long int u;
unsigned char * pu = reinterpret_cast<unsigned char *>(&u);
std::copy(buf, buf + sizeof(double), pu);
For this you have to bear several things in mind: the size of the integer has to be sufficient (a static assertion for sizeof(double) <= sizeof(unsigned long long int) should do the trick), and if the integer is in fact larger, then you're only copying into parts of it. I'm sure you'll figure that out, though :-) (You could use some template magic to create an integer of the correct size, if you really wanted.)
#include <stdint.h>
static inline uint64_t doubleToRawBits(double x) {
uint64_t bits;
memcpy(&bits, &x, sizeof bits);
return bits;
}
I like unions for these kinds of things.
union double_and_buffer {
double d;
unsigned char byte_buff[ sizeof(double) ];
} dab;
dab.d = 1.0;
for ( int i = 0; i < sizeof(dab.byte_buff); ++i )
{
cout << hex byte_buff[ i ];
}
I think it makes it more clear what you're doing and lets the compiler do all the math.
Related
If I have a Java long value - say x - which should be interpreted as an unsigned value (i.e. 0x8000_0000_0000_0000 and higher should be interpreted as positive value) then how can I convert it to BigInteger?
Obviously, BigInteger.valueOf(x) would result in a negative value, and conversion to hexadecimals or bytes seems wasteful.
Actually, the conversion is pretty simple. You can use masking similar to converting unsigned integers to long:
Let's first create the mask as constant (this simply results in the least significant 32 bits set to 1):
private static final long UNSIGNED_INT_MASK = (1L << Integer.SIZE) - 1L;
then we can perform:
int unsignedInt = 0x8000_0000; // sample input value
long l = (long) unsignedInt & UNSIGNED_INT_MASK;
So for BigInteger we can create the mask like this (64 least significant bits set to 1):
// use "import static java.math.BigInteger.ONE;" to shorten this line
private static final BigInteger UNSIGNED_LONG_MASK = BigInteger.ONE.shiftLeft(Long.SIZE).subtract(BigInteger.ONE);
great, then the rest will be easy:
long unsignedLong = 0x8000_0000_0000_0000L; // sample input value
BigInteger bi = BigInteger.valueOf(unsignedLong).and(UNSIGNED_LONG_MASK);
It's not rocket science, but sometimes you just want to find a quick and easy answer.
This conversion is actually implemented in java.lang.Long in OpenJDK: Long.java:241. It's private though, so pasting it here:
/**
* Return a BigInteger equal to the unsigned value of the
* argument.
*/
private static BigInteger toUnsignedBigInteger(long i) {
if (i >= 0L)
return BigInteger.valueOf(i);
else {
int upper = (int) (i >>> 32);
int lower = (int) i;
// return (upper << 32) + lower
return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
}
}
An extensive article on unsigned long and alternatives is available on my blog: Unsigned long in Java
I was reading Unsigned arithmetic in Java which nicely explained how to do unsigned longs using the following method
public static boolean isLessThanUnsigned(long n1, long n2) {
return (n1 < n2) ^ ((n1 < 0) != (n2 < 0));
}
However I'm confused by Guava's implementation. I'm hoping someone can shed some light on it.
/**
* A (self-inverse) bijection which converts the ordering on unsigned longs to the ordering on
* longs, that is, {#code a <= b} as unsigned longs if and only if {#code flip(a) <= flip(b)} as
* signed longs.
*/
private static long flip(long a) {
return a ^ Long.MIN_VALUE;
}
/**
* Compares the two specified {#code long} values, treating them as unsigned values between
* {#code 0} and {#code 2^64 - 1} inclusive.
*
* #param a the first unsigned {#code long} to compare
* #param b the second unsigned {#code long} to compare
* #return a negative value if {#code a} is less than {#code b}; a positive value if {#code a} is
* greater than {#code b}; or zero if they are equal
*/
public static int compare(long a, long b) {
return Longs.compare(flip(a), flip(b));
}
Perhaps some diagrams help. I'll use 8 bit numbers to keep the constants short, it generalizes to ints and longs in the obvious way.
Absolute view:
Unsigned number line:
[ 0 .. 0x7F ][ 0x80 .. 0xFF]
Signed number line:
[ 0x80 .. 0xFF ][ 0 .. 0x7F]
Relative view:
Unsigned number line:
[ 0 .. 0x7F ][ 0x80 .. 0xFF]
Signed number line:
[ 0x80 .. 0xFF ][ 0 .. 0x7F]
So signed and unsigned numbers largely have the same relative order, except that the two ranges with the sign bit set and the sign bit not set are swapped in order. Inverting that bit of course swaps the order.
x ^ Long.MIN_VALUE inverts the sign bit for a long.
This trick is applicable for any operation that depends only on the relative order, for example comparisons and directly related operations such as min and max. It does not work for operations that depend on the absolute magnitude of the numbers, such as division.
Consider the bits that make up a long type. Performing ^ Long.MIN_VALUE converts a regular two's complement signed representation that holds [-263, 263-1] values into an unsigned representation that holds [0, 264-1] values.
You can see the process by taking the smallest long value, adding one and "flipping" while inspecting the bits (e.g. with Long.toBinaryString()):
Long.MIN_VALUE ^ Long.MIN_VALUE is 00..00 (all 64 bits unset)
(Long.MIN_VALUE + 1) ^ Long.MIN_VALUE is 00..01
(Long.MIN_VALUE + 2) ^ Long.MIN_VALUE is 00..10
(Long.MIN_VALUE + 3) ^ Long.MIN_VALUE is 00..11
and so on until:
Long.MAX_VALUE ^ Long.MIN_VALUE is 11..11 (all 64 bits set)
The "flip" is done because Longs.compare() needs input as unsigned [0, 264-1] values as per the method javadoc in your example:
/**
* Compares the two specified {#code long} values, treating them as unsigned values between
* {#code 0} and {#code 2^64 - 1} inclusive.
*
I am trying to use java.lang.Math.IEEEremainder(double f1, double f2) in GWT. But I got below exception.
[ERROR] Line 1119: The method IEEEremainder(double, double) is
undefined for the type Math
I attempted to execute this code : angle = Math.IEEEremainder(angle, 360.0);
How to solve this issue in GWT?. If its not solve then what would be the alternative way to achieve the same functionality of Math.IEEEremainder this method.
According to the JRE Emulation this function is not supported in GWT.
So if you really need it and can't work around it, you will need to implement it yourself.
If I understand it correctly, you are trying to limit the angle to 360 degrees.
You could achieve that with this code:
/**
* Normalize a degree value.
* #param d value
* #return 0<=value<=360
*/
public static double normalizeDegrees(double d)
{
while (d < 0)
{
d += 360;
}
while (d > 360)
{
d -= 360;
}
return d;
}
If you just got positive numbers, you can even skip the upper while-Block.
If you really need to have the IEEEremainder method in GWT, implement it like that:
/**
* Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard. The remainder value is
* mathematically equal to <code>f1 - f2</code> × <i>n</i>, where <i>n</i> is the
* mathematical integer closest to the exact mathematical value of the quotient {#code f1/f2}, and if two
* mathematical integers are equally close to {#code f1/f2}, then <i>n</i> is the integer that is even. If the
* remainder is zero, its sign is the same as the sign of the first argument. Special cases:
* <ul>
* <li>If either argument is NaN, or the first argument is infinite, or the second argument is positive zero or
* negative zero, then the result is NaN.
* <li>If the first argument is finite and the second argument is infinite, then the result is the same as the first
* argument.
* </ul>
* #param f1 the dividend.
* #param f2 the divisor.
* #return the remainder when {#code f1} is divided by {#code f2}.
*/
public static double IEEEremainder(double f1, double f2)
{
double div = Math.round(f1 / f2);
return f1 - (div * f2);
}
(I added this as a new comment to show the syntax highlighting).
If I have the following code:
long interval = 0;
interval = ((6000 * 60) * 24) * 30;
It won't run because I would need to make every literal a Long. So this would work:
interval = ((6000L * 60L) * 24L) * 30L;
But what if I'm trying to multiply different variables that are in type char? Say I have:
char a, b, c, d;
And I give each of these chars a number value so I try:
interval = a * b * c * d;
If this overflows, I can't just put the L because that would call different variables.
interval = aL * bL * cL * dL;
I have tried converting each of these chars into a long before hand but the product still returns a negative number.
You just have to cast (any) one of the variables to long in order for long multiplication to take place :
interval = (long)a * b * c * d;
interval = ((6000L * 60L) * 24L) * 30L;
This code seems to be calculating the number of milliseconds in 30 days.
Well, then, use what the JDK has to offer:
interval = TimeUnit.DAYS.toMillis(30L);
javadoc for TimeUnit
When applying the multiplicative operator to its operands,
Binary numeric promotion is performed on the operands (§5.6.2).
That is, for this case,
Otherwise, if either operand is of type long, the other is converted to long.
So, really, all you need is to have one long value at the beginning of the multiplication. You can achieve this in a few ways. Either use a cast as demonstrated by Eran. Or use a long literal in the expression
char a, b, c, d;
...
interval = 1L * a * b * c * d;
// (......) result is a long value
By beginning of the multiplication, I'm referring to the fact that multiplicative operator is left associative. In your example, if the result of the first application of * is a long value, it will propagate to the next *.
I have the rather simple method naf
public int naf(int NN, int AA, int FF, int Q) {
int mike = FF + 0x20 * AA + 0x200 * NN;
if (Q == 1) {
mike += 0x4000;
}
return mike;
}
I can understand that this method accepts 4 integers and returns an integer. In the second line, the calculations are a bit confusing. I feel that the 0x parts have to do with hexadecimal number format, but the input arguments are in decimal. I have also the feeling that the 0x may make those calculations doable, but I am not certain.
What does the 0x offer and how can the method make hexadecimal calculations, when the input is decimal?
There's no such thing as hexadecimal calculations.
You have an integer expression, it is just that in it
two numbers are represented in hexadecimal format.
This
int mike = FF + 0x20*AA + 0x200 * NN;
is the same as:
int mike = FF + 2 * 16 * AA + 2 * 16 * 16 * NN;
which is the same as:
int mike = FF + 32 * AA + 512 * NN;
For a computer it doesn't matter how numbers are presented to you, be it decimal (base 10, as we're naturally familiar with), hexadecimal (base 16), octal (base 8), binary (base 2), you name it (though in Java only octal, decimal and hexadecimal are possible out of the box). Internally they are all stored as binary numbers, that's a series of zeros and ones.
In your code you are free to choose the format you feel most comfortable with. By default the Java compiler assumes you are feeding it decimal numbers, but by prefixing your number either with 0x or only 0 you tell it to interpret them as hexadecimal or octal numbers, respectively.
I suggest you try to read up on numeral systems.
Integer literals in java can be in the form of decimal (eg. 32), hexadecimal (eg. 0x20) and octal (eg. 040). The differences being decimal: no prefix, hexadecimal: prefix 0x and octal: prefix 0.
Thus,
int mike = FF + 0x20 * AA + 0x200 * NN;
is really just
int mike = FF + 32 * AA + 512 * NN;
Oh and the fact that FF is also on "hex form" doesn't matter at all, it's just a method parameter and might as well be called steven... :-)
Cheers,
Decimal or hexadecimal only applies when you express literals, e.g.:
int a = 0xfa; // hexadecimal notation for literal on the right hand side
int b = 251; // decimal notation for the literal on the right hand side
Once the values have been stored in variables the system doesn't care if you used decimal or hexadecimal notation to express the values that you stored:
int c = a + b; // numbers are added, regardless of you they were expressed above