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

28

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

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

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

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

  • 0
    Yikes, хорошая информация. У меня есть проект, где я передаю int64 туда-сюда, мне нужно вернуться и проверить это!
  • 0
    Одна мысль - если вы возвращаете java.lang.Long, а не long, вы можете (в matlab) сделать .toString () и вывести результат в виде строки, а затем преобразовать обратно в matlab.
Показать ещё 6 комментариев
Теги:
type-conversion

2 ответа

0
Лучший ответ

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

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

3

Если результат 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;
}
  • 0
    Это хорошо знать. Это не решение «задавай и забывай», потому что, например, число наносекунд с начала эпохи (1970 г.) больше этого числа (именно это и привело к публикации вопроса на самом деле), и в общем случае вы можете упаковать пиксели. в longs, или упаковать в них некоторые другие данные - не повседневная ситуация, но может случаться время от времени.
  • 0
    Кроме того, я думал, что volatile s только помогают с многопоточным кодом?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню