0

I am writing a JNI code and encounter a situation where I will need convert uint64_t to jlong, and here's my current way to convert uint64_t to jlong:

jlong uint64_t_to_jlong (uint64_t value) {
  if (value > std::numeric_limits<jlong>::max()) {
    return std::numeric_limits<jlong>::max(); 
  }
  return static_cast<jlong>(value);
}

And this is obviously not a perfect approach as it can't really convert the value correctly when value > std::numeric_limits<jlong>::max(). However, directly returning static_cast<jlong>(value) doesn't sound a good approach to me either, as in the Java side we will receive negative value.

Can I know whether there exist better approach which can handle all cases smoothly and correctly?

keelar
  • 5,814
  • 7
  • 40
  • 79
  • What do you want to happen when the value is greater than 2^63? Your only options are cast to the corresponding negative value or throw an exception, since Java doesn't have an unsigned 64-bit primitive integer type. – Adam Rosenfield Nov 17 '14 at 00:41
  • So is there any standard way to convert such negative value in the Java side? I am worried about whether it is platform specific stuff or not. – keelar Nov 17 '14 at 00:45
  • Java code can treat a signed long as unsigned, but you have to be careful about it. – Louis Wasserman Nov 17 '14 at 01:06
  • @LouisWasserman: Can I know more about the process of treating a signed long as unsigned in Java? esp. for 64-bit int. – keelar Nov 17 '14 at 05:37
  • Addition, subtraction, and multiplication are the same for signed and unsigned values; it's only division, remainder, comparison, and string conversion which you have to worry about. Java 8 provides libraries to do those for you, failing that you could use Guava's [unsigned libraries](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/primitives/UnsignedLongs.html) or reimplement them yourself. – Louis Wasserman Nov 17 '14 at 17:53
  • Can you point me which Java 8 function can to this? – keelar Nov 17 '14 at 19:17

1 Answers1

0

As suggested in the comment by Louis, one way to handle it in Java 8 is to simply cast uint64_t to jlong in the C++ side, then use the set of unsigned operation provided by Java 8 such as Long.compareUnsigned() to do the necessary operation:

public static int compareUnsigned(long x, long y)
Compares two long values numerically treating the values as unsigned.

Google Guava's unsigned libraries can also achieve this in case Java 8 is not used.

Iulian Popescu
  • 2,595
  • 4
  • 23
  • 31
keelar
  • 5,814
  • 7
  • 40
  • 79