Từ 1 tới 10 trên tổng số 10 kết quả

Đề tài: Làm sao để trình biên dịch phải chọn lưu số theo little endian hoặc big endian theo ý của mình

  1. #1
    Ngày gia nhập
    12 2015
    Nơi ở
    Đà Nẵng
    Bài viết
    398

    Mặc định Làm sao để trình biên dịch phải chọn lưu số theo little endian hoặc big endian theo ý của mình

    Mình mới vừa mới biết visual studio 2012 lưu số theo little endian, không biết version khác hay trình biên dịch khác như thế nào?
    Câu hỏi như tiêu đề

  2. #2
    Ngày gia nhập
    12 2015
    Nơi ở
    Đà Nẵng
    Bài viết
    398

    Vậy không có built in function để làm điều này rồi

  3. #3
    Ngày gia nhập
    01 2008
    Nơi ở
    Rất đông người
    Bài viết
    504

    Nếu dùng gcc thì bạn có thể viết như thế này.
    C Code:
    1. typedef struct abc
    2. {
    3.     int a;
    4.     long b;
    5.     short c;
    6.     float d;
    7.     float e[10];
    8. } abc_t;
    9.  
    10. typedef struct __attribute__ ((scalar_storage_order ("big-endian"))) ijk
    11. {
    12.     char  i;
    13.     short j;
    14.     int   k;
    15.     int   m[100];
    16.     abc_t p;
    17.     abc_t q[4];
    18. } ijk_t;
    19.  
    20. ijk_t x[1000];

    Khai báo trên lưu dưới dạng big endian tất cả các thành phần vô hướng (char, int, float,...) của struct ijk (cụ thể, thành phần i, j, k) cũng như cả các thành phần là mảng có phần tử vô hướng (cụ thể, thành phần m). Nó không tác động đến thành phần là struct hay union. Cụ thể, mọi thành phần con bên trong thành phần p và thành phần q vẫn được lưu ở endian mặc định.

    Chú ý. Cách viết này chỉ hợp lệ cho struct, union. Có thể lấy địa chỉ của 1 struct/union như thế, nhưng không được lấy địa chỉ của 1 thành phần của struct/union như thế. Hai biến cùng kiểu nhưng có endian khác nhau xem như thuộc về hai kiểu khác nhau.

    Xem thêm: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#Common-Type-Attributes
    Đã được chỉnh sửa lần cuối bởi Ada : 16-08-2018 lúc 05:54 PM. Lý do: Chính xác hóa
    -...- -.- .. .-.. .-.. - .... . -... . .- ... - .-.-.

  4. #4
    Ngày gia nhập
    12 2015
    Nơi ở
    Đà Nẵng
    Bài viết
    398

    ...................

  5. #5
    Ngày gia nhập
    07 2011
    Bài viết
    454

    xài Boost.Endian nè:

    C++ Code:
    1. int32_t x;
    2.  
    3. ... read into x from a file ... //giả sử file binary lưu với dạng big endian
    4.  
    5. big_to_native_inplace(x); //chuyển giá trị big endian thành native endian (ví dụ Win là little endian, Mac là big endian)
    6. x += 100;
    7. native_to_big_inplace(x); //chuyển lại thành big endian
    8.  
    9. ... write x to a file ...

    https://github.com/boostorg/endian
    Đã được chỉnh sửa lần cuối bởi INTP : 24-08-2018 lúc 09:26 PM.

  6. #6
    Ngày gia nhập
    01 2008
    Nơi ở
    Rất đông người
    Bài viết
    504

    Mặc định Làm sao để trình biên dịch phải chọn lưu số theo little endian hoặc big endian theo ý của mình

    Bạn ấy hỏi cách lưu (store), chứ không hỏi cách chuyển (convert). Chuyển có nhiều cánh. Nhưng lưu thì không có cách nào (portable giữa nhiều bộ biên dịch) cả, vì không có chuẩn.
    -...- -.- .. .-.. .-.. - .... . -... . .- ... - .-.-.

  7. #7
    Ngày gia nhập
    07 2011
    Bài viết
    454

    lưu dưới dạng mình chọn trước, ví dụ chọn là big endian, khi đọc lên đọc vào big endian, rồi convert thành native để tính toán, rồi khi lưu thì chuyển lại thành big endian rồi lưu thôi @_@

    https://wandbox.org/permlink/zQSGo14Y4cqLAzcf

    C++ Code:
    1. #include <iostream>
    2. #include <boost/endian/conversion.hpp>
    3.  
    4. int main()
    5. {
    6.     int a = 0x30313233; //1 số native endian
    7.     std::cout << "a = 0x" << std::hex << a << "\n";
    8.     std::cout << "native: ";
    9.     std::cout.write(static_cast<char*>(static_cast<void*>(&a)), 4); //khi lưu xuống "file" dạng native endian
    10.     std::cout << "\n";
    11.    
    12.     boost::endian::native_to_big_inplace(a);  //chuyển thành big endian
    13.     std::cout << "big: ";
    14.     std::cout.write(static_cast<char*>(static_cast<void*>(&a)), 4); //lưu xuống "file", bảo đảm dạng big endian
    15.     std::cout << "\n\n";
    16.    
    17.     int b;
    18.     std::cin.read(static_cast<char*>(static_cast<void*>(&b)), 4); //đọc lên từ big endian
    19.     std::cout << "b = 0x" << std::hex << b << "\n"; //0x37363534 sai, đúng ra phải là 0x34353637
    20.     std::cout << "big: ";
    21.     std::cout.write(static_cast<char*>(static_cast<void*>(&b)), 4);
    22.     std::cout << "\n";
    23.    
    24.     boost::endian::big_to_native_inplace(b);  //chuyển thành native endian
    25.     std::cout << "native: ";
    26.     std::cout.write(static_cast<char*>(static_cast<void*>(&b)), 4);
    27.     std::cout << "\nb = 0x" << std::hex << b << "\n"; //chuyển về đúng 0x34353637
    28. }

    input là 4567

    kết quả
    Code:
    a = 0x30313233
    native: 3210
    big: 0123
    
    b = 0x37363534
    big: 4567
    native: 7654
    b = 0x34353637

    .
    .
    .
    ồ chắc ý của Ada là tự động chuyển cả cái struct đó à? Có lẽ phải convet từng member thành 1 endian chuẩn trước rồi mới lưu được, đọc lên phải làm tương tự, phải viết hàm save/load riêng, cũng khổ Mà hình như chủ thớt chỉ hỏi lưu số thôi mà
    Đã được chỉnh sửa lần cuối bởi INTP : 25-08-2018 lúc 12:28 AM.

  8. #8
    Ngày gia nhập
    12 2015
    Nơi ở
    Đà Nẵng
    Bài viết
    398

    À, ý mình khi nói lưu là lưu trong bộ nhớ khi chương trình chạy, cái này Ada hiểu đúng ý mình, và cái mình muốn là giả sử có một phép gán "a=1000;" thì chương trình tự hiểu là phải lưu biến theo little hoặc big endian mà không cần gọi một hàm chuyển nào

    - - - Nội dung đã được cập nhật ngày 27-08-2018 lúc 08:41 PM - - -

    Vấn đề này nảy ra khi mình thử làm một chương trình tính toán số lớn, số lớn mình định nghĩa 3 kiểu là vector<unsigned char> hoặc vector<unsigned short> hoặc vector<unsigned int>, mỗi phần tử của vector là một chữ số trong hệ cơ số 2^8, 2^16, 2^32, và mình muốn có hàm chuyển giữa các kiểu với nhau, nếu số little endian thì không phải là gì cả, nếu big endian thì đảo một số byte, cách để biết hệ thống dùng little hay big endian mình đã biết sau khi tìm kiếm trên mạng nên đã viết được hàm chuyển, và mình cũng đã tìm được cách khác không cần quan tâm đến order là phép bitwise. Nhưng mình cũng muốn biết thêm về điều này

  9. #9
    Ngày gia nhập
    07 2011
    Bài viết
    454

    muốn tự động thì Boost.Endian cũng có big_int32_t hay little_int32_t đó, có đủ kích thước: https://www.boost.org/doc/libs/1_68_...rithmetic.html

    nếu mục đích là tính toán số lớn thì có thư viện MPIR/MPFR trên Windows và GMP trên Linux rồi, khỏi cần viết chi cho mệt, hoặc nếu ngại license LGPL/GPL thì có thể xài Boost.Multiprecision cpp_int: https://www.boost.org/doc/libs/1_68_...ision/tut.html (chậm hơn GMP/MPIR).

    nếu xài VS 2015+ thì dùng git clone cái vcpkg về rồi gõ
    Code:
    bootstrap-vcpkg
    vcpkg integrate install
    vcpkg install boost mpir mpfr
    rồi mở VS tạo project xài vô tư thôi

    C++ thiếu cái gì cứ mò trong Boost chắc 95% là có @_@
    Đã được chỉnh sửa lần cuối bởi INTP : 29-08-2018 lúc 07:38 AM.

  10. #10
    Ngày gia nhập
    12 2015
    Nơi ở
    Đà Nẵng
    Bài viết
    398

    Trích dẫn Nguyên bản được gửi bởi INTP Xem bài viết
    muốn tự động thì Boost.Endian cũng có big_int32_t hay little_int32_t đó, có đủ kích thước: https://www.boost.org/doc/libs/1_68_...rithmetic.html

    nếu mục đích là tính toán số lớn thì có thư viện MPIR/MPFR trên Windows và GMP trên Linux rồi, khỏi cần viết chi cho mệt, hoặc nếu ngại license LGPL/GPL thì có thể xài Boost.Multiprecision cpp_int: https://www.boost.org/doc/libs/1_68_...ision/tut.html (chậm hơn GMP/MPIR).

    nếu xài VS 2015+ thì dùng git clone cái vcpkg về rồi gõ
    Code:
    bootstrap-vcpkg
    vcpkg integrate install
    vcpkg install boost mpir mpfr
    rồi mở VS tạo project xài vô tư thôi

    C++ thiếu cái gì cứ mò trong Boost chắc 95% là có @_@
    Trang web hay,
    Thanks!

Tags của đề tài này

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn