Công cụ bảo vệ mã nguồn .NET mạnh nhất, không thể unpack, miễn phí cho các khách hàng đầu tiên đăng ký.
Từ 1 tới 5 trên tổng số 5 kết quả

Đề tài: Xử lí bit, kết quả lạ quá:(

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

    Mặc định Xử lí bit, kết quả lạ quá:(

    C++ Code:
    1. #include <string>
    2. #include <iostream>
    3. using namespace std;
    4. ////////////////////////////////
    5. class BitsDisplay
    6. {
    7. public:
    8.     static string display(unsigned long long value, char bitsCount)
    9.     {
    10.         char bit;
    11.         string str="";
    12.         while(bitsCount>0)
    13.         {
    14.             bit=value&1;
    15.             value>>=1;
    16.             str=(bit==1?"1":"0")+str;
    17.             bitsCount--;
    18.         }
    19.         if(value!=0)
    20.         {
    21.             throw "Bits overflow";
    22.         }
    23.         return str;
    24.     }
    25. };
    26. int main()
    27. {
    28.     unsigned long long n=0;
    29.     unsigned char bt=254;
    30.     unsigned long long m;
    31.     char i=0;
    32.     //srand(time(NULL));
    33.     while(i<8)
    34.     {
    35.         //bt=rand()%256;
    36.         n|=bt<<8*i;
    37.         m=0;
    38.         m|=bt<<8*i;
    39.         cout<<BitsDisplay::display(n,64)<<":\n";
    40.         cout<<BitsDisplay::display(m,64)<<"*\n";
    41.         i++;
    42.     }
    43. }
    44. //ket qua
    45. /*
    46. 0000000000000000000000000000000000000000000000000000000011111110:
    47. 0000000000000000000000000000000000000000000000000000000011111110*
    48. 0000000000000000000000000000000000000000000000001111111011111110:
    49. 0000000000000000000000000000000000000000000000001111111000000000*
    50. 0000000000000000000000000000000000000000111111101111111011111110:
    51. 0000000000000000000000000000000000000000111111100000000000000000*
    52. 1111111111111111111111111111111111111110111111101111111011111110:
    53. 1111111111111111111111111111111111111110000000000000000000000000*
    54. 1111111111111111111111111111111111111110111111101111111011111110:
    55. 0000000000000000000000000000000000000000000000000000000011111110*
    56. 1111111111111111111111111111111111111110111111101111111011111110:
    57. 0000000000000000000000000000000000000000000000001111111000000000*
    58. 1111111111111111111111111111111111111110111111101111111011111110:
    59. 0000000000000000000000000000000000000000111111100000000000000000*
    60. 1111111111111111111111111111111111111110111111101111111011111110:
    61. 1111111111111111111111111111111111111110000000000000000000000000*
    62.  
    63. */
    Các bạn cho ý kiến???
    Code trên là như thế nào
    Biến bt mang giá trị 254, dạng bit là 11111110. Mình gán 8 bit từ vị trí 0 tới 7(từ phải sang trái) của n giá trị 254, sau đó , bit 8-15, bit 16-23 cũng gán 254. Tuy nhiên khi gán bit 24-31 thì từ bit 32 sang trái đều biến thành 1, tiếp theo đó vẫn tiếp tục gán cho bit 32-39, bit 40-47,bit 48-55, bit 56-63 thì kết quả như comment phía trên, các dòng có ":" ở cuối
    Biến m cũng được gán 254 cho các đoạn 8 bit như trên nhưng trước đó được gán giá trị 0, các dòng có "*" ở cuối
    Từ đó mình phát hiện ra là thay vì gán bit 32-39(của biến m) thì nó gán bit 0-7, thay vì bit 40-47 thì bit 8-15, bit 16-23 thay cho bit 48-55, bit 24-31 thay cho bit 56-63, và khi này các bit từ 32 tới 63 đều biến thành 1.
    Vậy đó, có chuyện gì với phép toán xử lí bit vậy, mình đoán là phép dịch bit, mong các bạn chỉ giáo.

    - - - Nội dung đã được cập nhật ngày 30-10-2019 lúc 07:02 AM - - -

    Mình sửa kiểu của biến bt thành unsigned int, kết quả gần như cũ nhưng vụ bit 32 trở đi biến thành 1 biến mất. Sửa thành unsigned long long thì kết quả như mong đợi.
    Mình vẫn đang chờ 1 câu giải thích
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.
    Đã được chỉnh sửa lần cuối bởi khoaph : 29-10-2019 lúc 08:25 PM.

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

    Mình không có compiler để kiểm chứng nhưng cơ bản mình nghĩ là thế này. Biểu thức bt << 8*i có kiểu có dấu, có lẽ là int. Khi đưa vào làm toán hạng phải cho toán tử |= nó được mở rộng để có cùng độ dài với toán hạng trái n, nhưng vẫn có dấu, nghĩa là nó trở thành long long int. Vì thế mà phát sinh chuỗi 1111.... ở đầu.
    -...- -.- .. .-.. .-.. - .... . -... . .- ... - .-.-.

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

    Mình có thể xác nhận biểu thức bt << 8*i có kiểu int (tức signed int) hoặc unsigned (tức unsigned int). Điều này đúng một cách tổng quát hơn, biểu thức A << B, với A có kiểu char hay unsigned char, sẽ có kiểu int hoặc unsigned. Trong đó, int là nói chung, còn unsigned là ngoại lệ.

    Ngoại lệ này chỉ xảy ra trong cài đặt mà kiểu charint có cùng kích thước hay nói cách khác, nơi độ dài ô nhớ (byte) bằng độ dài thanh ghi. Nếu cài đặt tuân thủ định nghĩa một byte là một octet (tức 8 bit) vốn đã trở thành tiêu chuẩn từ 30 năm nay, ngoại lệ này chỉ xảy ra trên cài đặt 8 bit.

    Việc ngầm đổi kiểu thành int từ một kiểu có kích cỡ nhỏ hơn int, tiếng Anh gọi là integer promotion và, nói riêng, việc làm cho biểu thức A << B có kiểu int, hơn là kiểu của A, là một đặc sản của ngôn ngữ C/C++. Một đặc sản trái với trực giác của con người, đôi khi gây lúng túng cho lập trình viên.
    -...- -.- .. .-.. .-.. - .... . -... . .- ... - .-.-.

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

    thêm vài cái reference:

    Bitwise shift operators
    The return type is the type of the left operand after integral promotions.
    kiểu trả về của lhs << rhs là kiểu của lhs, sau khi thực hiện integer promotion

    unsigned char, char8_t (since C++20) or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise;
    kiểu unsigned char có thể được promote lên thành kiểu int hoặc unsigned int nếu int ko chứa nổi tất cả giá trị của biến unsigned char đó.

    Có phải unsigned char luôn luôn được promote thành int?
    For example, TI C compiler for TMS320C55x: CHAR_BIT is 16 and UCHAR_MAX 65535, UINT_MAX 65535 but INT_MAX 32767.
    câu trả lời là ko, 1 số compiler có UCHAR_MAX > INT_MAX sẽ promote unsigned char thành unsigned int.

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

    Roa dzậy, thanks các bạn
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.

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