2013-05-01 32 views
28

Theo Matlab documentation, khi phương thức Java trả về long, nó được chuyển thành double trước khi được gán trong Matlab.MATLAB - Cách nhận int64 từ một phương thức Java trả về một thời gian dài?

Độ chính xác đã bị mất. Tôi quan tâm đến các chữ số dưới của số long được trả về bằng phương thức Java. A double không thể đại diện cho chúng, nhưng số int64 của Matlab có thể. (Điều này là rõ ràng bằng cách xem xét rằng cả hai loại có 64 bit, và một số double sử dụng một số trong số chúng để đại diện cho số mũ.)

Nếu tôi có quyền kiểm soát mã Java, tôi có thể trả về một mảng với một phần tử, chứa long - trong trường hợp này Matlab giữ chúng là int64 s, nhưng trong trường hợp của tôi, tôi gọi hàm thư viện.

Hiện tại, cách tốt nhất tôi có thể thấy là viết trình bao bọc trong Java sẽ gọi phương thức và trả về câu trả lời trong một mảng. Nhưng có những vấn đề về tính di động với phương pháp này. Có cách nào tốt hơn?

+0

Yikes, thông tin tốt. Tôi có một dự án mà tôi đang đi qua xung quanh int64s qua lại, tôi sẽ cần phải quay trở lại và kiểm tra này! – JonB

+0

Một suy nghĩ - nếu bạn trả về một java.lang.Long thay vì dài, bạn có thể (trong MATLAB) làm .toString() và mang lại kết quả như là một chuỗi, và chuyển đổi trở lại trong MATLAB. – JonB

+0

tức là Matlab có thể lấy int64 bằng cách sử dụng sscanf (char (wrapperFun(). ToString), '% ld'). – JonB

Trả lời

0

Nó được về cơ bản đã trả lời trong các ý kiến, nhưng chỉ cho đầy đủ, cách tốt nhất để nhận được một Java long vào Matlab như int64 không hề hấn gì dường như được viết một wrapper Java nhỏ trong đó kêu gọi bất cứ phương pháp bạn có và lợi nhuận phản hồi trong một số long[].

(Nếu mã được phân phối, hãy xem xét biên dịch lớp Java đó bằng phiên bản JVM mục tiêu sớm hơn phiên bản mới nhất - nếu không một số người dùng sẽ buộc phải nâng cấp JVM của họ để chạy phần mềm của bạn sẽ không có quyền quản trị để làm điều đó.)

3

Nếu kết quả trả về phương thức Java nằm trong khoảng [-9,007,199,254,740,992 đến 9,007,199,254,740,992], thì bạn không cần làm gì cả trong mã của mình. Bạn có thể chuyển đổi kết quả trở lại thành Matlab's int64, mà không mất bất kỳ độ chính xác nào. Tất cả các số nguyên trong phạm vi đó có thể được biểu diễn dưới dạng số double mà không bị mất chính xác, bởi vì giá trị có thể được lưu trữ trong các số nhị phân đáng kể 53 bit được cung cấp bởi biểu diễn 64 bit của các giá trị double.

Bạn có thể tìm thêm chi tiết trong Chương 8 (Số học dấu chấm động) của cuốn sách Code Quality: The Open Source Perspective hoặc bất kỳ sách giáo khoa nào khác bao gồm số học dấu chấm động.

Chương trình sau đây thể hiện độ chính xác của đại diện double cho 100 triệu số nguyên ở cuối phạm vi chính xác thể hiện được.

#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

Điều đó rất hữu ích. Đó không phải là giải pháp được thiết lập và quên, bởi vì, ví dụ, số nano giây từ kỷ nguyên (1970) lớn hơn con số đó (điều này dẫn đến việc đăng câu hỏi trên thực tế), và nói chung, bạn có thể đóng gói pixel lâu dài, hoặc đóng gói một số dữ liệu khác vào chúng - không phải là tình huống hàng ngày, nhưng có thể xảy ra theo thời gian. –

+0

Ngoài ra, tôi nghĩ rằng 'volatile's chỉ giúp với mã đa luồng? –

+0

'volatile' hướng dẫn trình biên dịch tránh tối ưu hóa mã liên quan đến biến đó. Nếu không có nó, một trình biên dịch tối ưu hóa thông minh có thể tối ưu hóa các phần của mã của tôi, bởi vì chúng không làm bất cứ điều gì hữu ích. –

Các vấn đề liên quan