Package com.github.tommyettinger.digital
Class BitConversion
java.lang.Object
com.github.tommyettinger.digital.BitConversion
Methods for converting floats to and from ints, as well as doubles to and from longs and ints.
This is like NumberUtils in libGDX, but is closer to a subset of NumberTools in SquidLib. It
includes methods like
floatToReversedIntBits(float)
(which is also in NumberTools, and
makes converting from an OpenGL packed ABGR float to an RGBA8888 int very easy) and
doubleToMixedIntBits(double)
(which is useful when implementing hashCode() for double
values). Everything's optimized for GWT, which is important because some core JDK methods like
Float.floatToIntBits(float)
are quite slow on GWT. This makes heavy use of JS typed
arrays to accomplish its conversions; these are widespread even on mobile browsers, and are very
convenient for this sort of code (in some ways, they're a better fit for this sort of bit-level
operation in JavaScript than anything Java provides).-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic int
doubleToHighIntBits
(double value) Converts the raw bits ofvalue
to a long and gets the upper 32 bits of that long, as an int.static long
doubleToLongBits
(double value) Identical toDouble.doubleToLongBits(double)
on desktop; optimized on GWT.static int
doubleToLowIntBits
(double value) Converts the raw bits ofvalue
to a long and gets the lower 32 bits of that long, as an int.static int
doubleToMixedIntBits
(double value) Converts the bits ofvalue
to a long and gets the XOR of its upper and lower 32-bit sections.static long
doubleToRawLongBits
(double value) Identical toDouble.doubleToRawLongBits(double)
on desktop; optimized on GWT.static long
doubleToReversedLongBits
(double value) Gets the bit representation of the given doublevalue
, but with reversed byte order.static int
floatToIntBits
(float value) Identical toFloat.floatToIntBits(float)
on desktop; optimized on GWT.static int
floatToRawIntBits
(float value) Identical toFloat.floatToRawIntBits(float)
on desktop; optimized on GWT.static int
floatToReversedIntBits
(float value) Gets the bit representation of the given floatvalue
, but with reversed byte order.static float
intBitsToFloat
(int bits) Identical toFloat.intBitsToFloat(int)
on desktop; optimized on GWT.static double
longBitsToDouble
(long bits) Identical toDouble.longBitsToDouble(long)
on desktop; optimized on GWT.static int
lowestOneBit
(int num) Returns an int value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified int value.static long
lowestOneBit
(long num) Returns an long value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified long value.static float
reversedIntBitsToFloat
(int bits) Reverses the byte order ofbits
and converts that to a float.static double
reversedLongBitsToDouble
(long bits) Reverses the byte order ofbits
and converts that to a double.
-
Constructor Details
-
BitConversion
public BitConversion()
-
-
Method Details
-
doubleToLongBits
public static long doubleToLongBits(double value) Identical toDouble.doubleToLongBits(double)
on desktop; optimized on GWT. When compiling to JS via GWT, there is no way to distinguish NaN values with different bits but that are still NaN, so this doesn't try to somehow permit that. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them. JS typed arrays support double, but not long, so this needs to compose a long from two ints, which means the double-to/from-long conversions aren't as fast as float-to/from-int conversions.
This method may be a tiny bit slower thandoubleToRawLongBits(double)
on non-HotSpot JVMs.- Parameters:
value
- adouble
floating-point number.- Returns:
- the bits that represent the floating-point number.
-
doubleToRawLongBits
public static long doubleToRawLongBits(double value) Identical toDouble.doubleToRawLongBits(double)
on desktop; optimized on GWT. When compiling to JS via GWT, there is no way to distinguish NaN values with different bits but that are still NaN, so this doesn't try to somehow permit that. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them. JS typed arrays support double, but not long, so this needs to compose a long from two ints, which means the double-to/from-long conversions aren't as fast as float-to/from-int conversions on GWT. Note that on GWT, the "Raw" conversions aren't available in Double or Float, and the versions here are identical to the "non-Raw" versions on GWT.- Parameters:
value
- adouble
floating-point number.- Returns:
- the bits that represent the floating-point number.
-
doubleToReversedLongBits
public static long doubleToReversedLongBits(double value) Gets the bit representation of the given doublevalue
, but with reversed byte order. On desktop, this is equivalent to callingLong.reverseBytes(Double.doubleToRawLongBits(value))
, but it is implemented using typed arrays on GWT. Note that this reverses byte order, not bit order.
This method runs at the expected speed on desktop and mobile, where it should compile down to two (very fast) intrinsics, but GWT should run it much more quickly than a direct translation of the Java would provide.- Parameters:
value
- any double- Returns:
- the bits that represent the floating-point value, with their byte order reversed from normal.
-
reversedLongBitsToDouble
public static double reversedLongBitsToDouble(long bits) Reverses the byte order ofbits
and converts that to a double. On desktop, this is equivalent to callingDouble.longBitsToDouble(Long.reverseBytes(bits))
, but it is implemented using typed arrays on GWT. Note that this reverses byte order, not bit order.
This method runs at the expected speed on desktop and mobile, where it should compile down to two (very fast) intrinsics, but GWT should run it much more quickly than a direct translation of the Java would provide.- Parameters:
bits
- a long- Returns:
- the
double
floating-point value with the given bits using their byte order reversed from normal.
-
longBitsToDouble
public static double longBitsToDouble(long bits) Identical toDouble.longBitsToDouble(long)
on desktop; optimized on GWT. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them. JS typed arrays support double, but not long, so this needs to compose a long from two ints, which means the double-to/from-long conversions aren't as fast as float-to/from-int conversions.- Parameters:
bits
- a long.- Returns:
- the
double
floating-point value with the same bit pattern.
-
doubleToLowIntBits
public static int doubleToLowIntBits(double value) Converts the raw bits ofvalue
to a long and gets the lower 32 bits of that long, as an int. This performs better on GWT than casting the result ofdoubleToRawLongBits(double)
to int, because it doesn't create along
internally on that platform, and longs are quite slow on GWT.- Parameters:
value
- adouble
precision floating-point number.- Returns:
- the lower half of the bits that represent the floating-point number, as an int.
-
doubleToHighIntBits
public static int doubleToHighIntBits(double value) Converts the raw bits ofvalue
to a long and gets the upper 32 bits of that long, as an int. This performs better on GWT than casting the result ofdoubleToRawLongBits(double)
to int, because it doesn't create along
internally on that platform, and longs are quite slow on GWT.- Parameters:
value
- adouble
precision floating-point number.- Returns:
- the upper half of the bits that represent the floating-point number, as an int.
-
doubleToMixedIntBits
public static int doubleToMixedIntBits(double value) Converts the bits ofvalue
to a long and gets the XOR of its upper and lower 32-bit sections. Useful for numerical code where a 64-bit double needs to be reduced to a 32-bit value with some hope of keeping different doubles giving different ints. This performs better on GWT than working withdoubleToRawLongBits(double)
and XORing its upper and lower halves, because it doesn't create along
internally on that platform, and longs are quite slow on GWT.- Parameters:
value
- adouble
precision floating-point number.- Returns:
- the XOR of the lower and upper halves of the bits that represent the floating-point number.
-
floatToIntBits
public static int floatToIntBits(float value) Identical toFloat.floatToIntBits(float)
on desktop; optimized on GWT. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them.
This method may be a tiny bit slower thanfloatToRawIntBits(float)
on non-HotSpot JVMs.- Parameters:
value
- a floating-point number.- Returns:
- the bits that represent the floating-point number.
-
floatToRawIntBits
public static int floatToRawIntBits(float value) Identical toFloat.floatToRawIntBits(float)
on desktop; optimized on GWT. When compiling to JS via GWT, there is no way to distinguish NaN values with different bits but that are still NaN, so this doesn't try to somehow permit that. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them. Note that on GWT, the "Raw" conversions aren't available in Double or Float, and the versions here are identical to the "non-Raw" versions on GWT.- Parameters:
value
- a floating-point number.- Returns:
- the bits that represent the floating-point number.
-
floatToReversedIntBits
public static int floatToReversedIntBits(float value) Gets the bit representation of the given floatvalue
, but with reversed byte order. On desktop, this is equivalent to callingInteger.reverseBytes(Float.floatToRawIntBits(value))
, but it is implemented using typed arrays on GWT. Note that this reverses byte order, not bit order.
This is primarily intended for a common task in libGDX's internals: converting between RGBA8888 int colors and ABGR packed float colors. This method runs at the expected speed on desktop and mobile, where it should compile down to two (very fast) intrinsics, but GWT should run it much more quickly than a direct translation of the Java would provide.- Parameters:
value
- a floating-point number- Returns:
- the bits that represent the floating-point number, with their byte order reversed from normal.
-
reversedIntBitsToFloat
public static float reversedIntBitsToFloat(int bits) Reverses the byte order ofbits
and converts that to a float. On desktop, this is equivalent to callingFloat.intBitsToFloat(Integer.reverseBytes(bits))
, but it is implemented using typed arrays on GWT. Note that this reverses byte order, not bit order.
This is primarily intended for a common task in libGDX's internals: converting between RGBA8888 int colors and ABGR packed float colors. This method runs at the expected speed on desktop and mobile, where it should compile down to two (very fast) intrinsics, but GWT should run it much more quickly than a direct translation of the Java would provide.- Parameters:
bits
- an integer- Returns:
- the
float
floating-point value with the given bits using their byte order reversed from normal.
-
intBitsToFloat
public static float intBitsToFloat(int bits) Identical toFloat.intBitsToFloat(int)
on desktop; optimized on GWT. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them.- Parameters:
bits
- an integer.- Returns:
- the
float
floating-point value with the same bit pattern.
-
lowestOneBit
public static int lowestOneBit(int num) Returns an int value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified int value. Returns zero if the specified value has no one-bits in its two's complement binary representation, that is, if it is equal to zero.
Identical toInteger.lowestOneBit(int)
, including on GWT. GWT calculates Integer.lowestOneBit() correctly, but does not always calculate Long.lowestOneBit() correctly. This overload is here so you can use lowestOneBit on an int value and get an int value back (which could be assigned to a long without losing data), or use it on a long value and get the correct long result on both GWT and other platforms.- Parameters:
num
- the value whose lowest one bit is to be computed- Returns:
- an int value with a single one-bit, in the position of the lowest-order one-bit in the specified value, or zero if the specified value is itself equal to zero.
-
lowestOneBit
public static long lowestOneBit(long num) Returns an long value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified long value. Returns zero if the specified value has no one-bits in its two's complement binary representation, that is, if it is equal to zero.
Identical toLong.lowestOneBit(long)
, but super-sourced to act correctly on GWT. At least on GWT 2.8.2,Long.lowestOneBit(long)
does not provide correct results for certain inputs on GWT. For example, when given -17592186044416L, Long.lowestOneBit() returns 0 on GWT, possibly because it converts to an int at some point. On other platforms, like desktop JDKs,Long.lowestOneBit(-17592186044416L)
returns 17592186044416L.- Parameters:
num
- the value whose lowest one bit is to be computed- Returns:
- a long value with a single one-bit, in the position of the lowest-order one-bit in the specified value, or zero if the specified value is itself equal to zero.
-