Search code examples
javabit-manipulationjnaunsigned

Simulating unsigned number with a certain power of two max in java


I have some output from a (C++) application that stores a tickcount value in a type that wraps to zero at 233. (8,589,934,592) (Don't have the code)

I need to write my own output in the same way. I retrieve the tickcount from a C lib through JNA, but if I store it in an int it wraps to -231 (-2,147,483,648) after ~25 days' tickcount and if I store it in a long it just keeps going past 233.

How can I store (or write) the value in Java in such a way that it wraps (to zero) at 233?

(Preferably a JRE7- & JRE8- on Win32- & Win64- & Linux-compatible solution)

To get the tickcount I use the following:

import com.sun.jna.*;
public interface Kernel32 extends Library {
    Kernel32 INSTANCE = (Kernel32) Native.loadLibrary((Platform.isWindows() ? "kernel32" : "c"), Kernel32.class);

    /**
     * Retrieves the number of milliseconds that have elapsed since the system was started.
     *
     * @return number of milliseconds that have elapsed since the system was started.
     * @see http://msdn2.microsoft.com/en-us/library/ms724408.aspx
     */
    Long GetTickCount();
}

public interface Clib extends Library {
    Clib INSTANCE = (Clib) Native.loadLibrary((Platform.isWindows() ? "kernel32" : "c"), Clib.class);

    /**
     * Retrieves the number of milliseconds that have elapsed since the system was started.
     *
     * @return number of milliseconds that have elapsed since the system was started.
     */
    Long clock();
}

// And later
Number n = (Platform.isWindows() ? Kernel32.INSTANCE.GetTickCount() : Clib.INSTANCE.clock()).toString());

Solution

  • You can store the value in a long, then truncate the value to 33 bits (wrapping 233 around to 0) by doing:

    n &= (1L << 33) - 1;
    

    This is exactly the same as:

    n &= 0x1_ffff_ffffL;
    

    which is also the same as:

    n &= 8_589_934_591L;