Class BitConversion

java.lang.Object
com.github.tommyettinger.digital.BitConversion

public final class BitConversion extends Object
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 Details

    • BitConversion

      public BitConversion()
  • Method Details

    • doubleToLongBits

      public static long doubleToLongBits(double value)
      Identical to Double.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 than doubleToRawLongBits(double) on non-HotSpot JVMs.
      Parameters:
      value - a double floating-point number.
      Returns:
      the bits that represent the floating-point number.
    • doubleToRawLongBits

      public static long doubleToRawLongBits(double value)
      Identical to Double.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 - a double 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 double value, but with reversed byte order. On desktop, this is equivalent to calling Long.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 of bits and converts that to a double. On desktop, this is equivalent to calling Double.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 to Double.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 of value to a long and gets the lower 32 bits of that long, as an int. This performs better on GWT than casting the result of doubleToRawLongBits(double) to int, because it doesn't create a long internally on that platform, and longs are quite slow on GWT.
      Parameters:
      value - a double 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 of value to a long and gets the upper 32 bits of that long, as an int. This performs better on GWT than casting the result of doubleToRawLongBits(double) to int, because it doesn't create a long internally on that platform, and longs are quite slow on GWT.
      Parameters:
      value - a double 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 of value 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 with doubleToRawLongBits(double) and XORing its upper and lower halves, because it doesn't create a long internally on that platform, and longs are quite slow on GWT.
      Parameters:
      value - a double 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 to Float.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 than floatToRawIntBits(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 to Float.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 float value, but with reversed byte order. On desktop, this is equivalent to calling Integer.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 of bits and converts that to a float. On desktop, this is equivalent to calling Float.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 to Float.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 to Integer.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 to Long.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.