Подтвердить что ты не робот

Matlab - Как получить int64 из метода Java, возвращающего long?

Согласно документации Matlab, когда Java-метод возвращает long, он преобразуется в double перед назначением в Matlab.

Точность была потеряна. Меня интересуют более низкие цифры long, возвращаемые методом Java. A double не может представлять их, но Matlab int64 может. (Это понятно, учитывая, что оба типа имеют 64 бита, а double использует некоторые из них для представления экспоненты.)

Если бы я имел контроль над Java-кодом, я мог бы вернуть массив с одним элементом, содержащий long - в этом случае Matlab сохраняет их как int64 s, но в моем случае я вызываю библиотечную функцию.

В настоящее время лучшим способом я могу написать обертку в Java, которая вызовет метод и вернет ответ в массиве. Но с этим подходом есть проблемы с переносимостью. Есть ли лучший способ?

4b9b3361

Ответ 1

В комментариях был дан ответ, но только для полноты, лучший способ получить Java long в Matlab как int64 невредим, похоже, пишет небольшую оболочку Java, которая вызывает любой метод, который у вас есть, и возвращает ответ в long[].

(Если код должен быть распространен, подумайте о компиляции этого класса Java с целевой версией JVM, которая несколько раньше последней - в противном случае некоторые пользователи будут вынуждены обновлять свою JVM для запуска вашего программного обеспечения, а некоторые из них выиграли у вас есть права администратора для этого.)

Ответ 2

Если результат long приведет к возврату вашего метода Java в диапазоне [-9,007,199,254,740,992 до 9,007,199,254,740,992], вам не нужно вообще ничего делать в своем коде. Вы можете преобразовать результат обратно в Matlab int64 без потери точности. Все целые числа в этом диапазоне могут быть представлены в виде double чисел без потери точности, потому что значение может быть сохранено в 53-битных значащих двоичных разрядах, предлагаемых 64-битным представлением double.

Более подробную информацию вы можете найти в главе 8 (Арифметика с плавающей запятой) моей книги Качество кода: перспектива с открытым исходным кодом или любой другой учебник покрывая арифметику с плавающей запятой.

Следующая программа демонстрирует точность представления double для 100 миллионов целых чисел в конце точно отображаемого диапазона.

#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;
}