简体   繁体   中英

matlab - How to get int64 from a Java method returning a long?

According to Matlab documentation , when a Java method returns a long , it is converted to a double before being assigned in Matlab.

Precision has been lost. I am interested in the lower digits of the long returned by the Java method. A double cannot represent them, but Matlab's int64 can. (This is clear by considering that both types have 64 bits, and a double uses some of them to represent the exponent.)

If I had control of the Java code, I could return an array with one element, containing the long — in this case Matlab keeps them as int64 s, but in my case I'm calling a library function.

Currently, the best way I can see is writing a wrapper in Java that will call the method and return the answer in an array. But there are portability issues with this approach. Is there a better way?

If the long results that your Java method returns are in the range [-9,007,199,254,740,992 to 9,007,199,254,740,992], then you don't need to do anything at all in your code. You can convert the result back to Matlab's int64 , without any loss of precision. All integers in that range can be represented as double numbers without a loss in precision, because the value can be stored in the 53-bit significant binary digits offered by the 64-bit representation of double values.

You can find more details in Chapter 8 (Floating-Point Arithmetic) of my book Code Quality: The Open Source Perspective or any other textbook covering floating point arithmetic.

The following program demonstrates the accuracy of the double representation for the 100 million integers at the end of the exactly representable range.

#include <stdio.h>

int
main(int argc, char *argv[])
{
    int i;
    volatile long long n1, n2;
    volatile long long p1, p2;
    volatile double d;

    /* Include one number outside the range, to show that the test works. */
    n1 = -9007199254740993ll;
    p1 =  9007199254740993ll;
    for (i = 0; i < 100000000; i++) {
        d = p1;
        p2 = d;
        if (p1 != p2)
            printf("%lld != %lld\n", p1, p2);

        d = n1;
        n2 = d;
        if (n1 != n2)
            printf("%lld != %lld\n", n1, n2);
        p1--;
        n1++;
    }
    return 0;
}

It's been essentially answered in the comments, but just for completeness, the best way to receive a Java long into Matlab as int64 unharmed does seem to be writing a small Java wrapper which calls whatever method you have and returns the response in a long[] .

(If the code is to be distributed, consider compiling that Java class with a target JVM version that is somewhat earlier than the latest — otherwise some users will be forced to upgrade their JVM to run your software, and some of those won't have admin rights to do that.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM