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

Đề tài: Nhân bằng giải thuật Booth, hình như là lỗi tràn số nhưng có trường hợp lạ xảy ra

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

    Mặc định Nhân bằng giải thuật Booth, hình như là lỗi tràn số nhưng có trường hợp lạ xảy ra

    Mình có đọc qua nhân bằng giải thuật Booth ở đây
    bc3a0i-gie1baa3i-thue1baadt-toc3a1n-booth.pdf
    rồi viết chương trình như vầy
    SignedNumber.h
    C++ Code:
    1. #include <string>
    2. using namespace std;
    3.  
    4. class SignedNumber
    5. {
    6. private:
    7.     signed char Number;
    8. public:
    9.     SignedNumber(signed char number):Number(number)
    10.         {}
    11.     string ToBinary();
    12.     short Multiply(SignedNumber);
    13.     void ShiftRight(signed char &, signed char &, char &);
    14. };
    SignedNumber.cpp
    C++ Code:
    1. #include "SignedNumber.h"
    2.  
    3. string SignedNumber::ToBinary()
    4. {
    5.     string BinaryString="";
    6.     short n=1;
    7.     for(int i=0;i<sizeof(Number)*8;i++)
    8.     {
    9.         if(Number&n!=0)//if(Number&n==n)
    10.         {
    11.             BinaryString="1"+BinaryString;
    12.         }
    13.         else
    14.         {
    15.             BinaryString="0"+BinaryString;
    16.         }
    17.         n=n<<1;
    18.     }
    19.     return BinaryString;
    20. }
    21. void SignedNumber::ShiftRight(signed char &A, signed char &Q ,char &Qminus1)
    22. {
    23.     //lưu bit thứ 0 lại
    24.     Qminus1=1&Q;
    25.     Q=Q>>1;
    26.     char i=1&A;
    27.     if(i==1)//if(i!=0)
    28.     {
    29.         i=1<<sizeof(char)*8-1;//i=1<<7
    30.         //bật bit thứ 7 về 1
    31.         Q=Q|i;
    32.     }
    33.     else
    34.     {
    35.         i=1<<sizeof(char)*8-1;
    36.         i=~i;
    37.         //tắt bit thứ 7 về 0
    38.         Q=Q&i;
    39.     }
    40.     A=A>>1;
    41. }
    42. short SignedNumber::Multiply(SignedNumber number)
    43. {
    44.     signed char Q=Number;
    45.     signed char M=number.Number;
    46.     signed char A=0;
    47.     char n=sizeof(char)*8;
    48.     char Qminus1=0;
    49.     while(n>0)
    50.     {
    51.         if((Q&1)==0&&(Qminus1&1)==1)
    52.         {
    53.             A+=M;
    54.         }
    55.         if((Q&1)==1&&(Qminus1&1)==0)
    56.         {
    57.             A-=M;
    58.         }
    59.         ShiftRight(A, Q, Qminus1);
    60.         n--;
    61.     }
    62.     short Result;
    63.     Result=1<<sizeof(char)*8;
    64.     Result*=A;
    65.     Result=Result|Q;
    66.     return Result;
    67. }
    68. static void main()
    69. {int aa, bb;
    70.     char c='c';
    71.     while(c=='c')
    72.     {
    73.     cout<<"Nhap so thu nhat:";
    74.     cin>>aa;
    75.     cout<<"Nhap so thu hai:";
    76.     cin>>bb;
    77.     SignedNumber m((signed char)aa);
    78.     SignedNumber p((signed char)bb);
    79.     getchar();
    80.     cout<<"Tich la:";
    81.     cout<<m.Multiply(p)<<endl;
    82.     cout<<"Co tiep tuc khong?(c/k)";
    83.     cin>>c;
    84.     }
    85.     getchar();
    86. }
    Kết quả đôi khi có lỗi đôi khi không, mình nghĩ có thể là do tràn số, nhưng mình thấy nhiều trường hợp số không cận biên(gần với giới hạn của kiểu dữ liệu) nhân với nhau vẫn cho kết quả sai
    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		Untitled.png
Lần xem:	3
Size:		24.1 KB
ID:		60664 chẳng hạn 14 nhân 14 ra số âm
    hóng cao nhân giải thích vì sao kết quả như vậy
    mình sử dụng kiểu dữ liệu nhỏ để tràn số có thể xảy ra, nhưng mình nghĩ nhân 2 số 1 byte với nhau theo gthuật Booth thì kết quả 2 byte là vừa đủ, không biết như vậy có đúng không?

    - - - Nội dung đã được cập nhật ngày 14-03-2018 lúc 07:06 AM - - -

    Quên khi shift phải giữ dấu của A
    C++ Code:
    1. void SignedNumber::ShiftRight(signed char &A, signed char &Q ,char &Qminus1)
    2. {
    3.     //lưu bit thứ 0 lại
    4.     Qminus1=1&Q;
    5.     Q=Q>>1;
    6.     char i=1&A;
    7.     if(i==1)//if(i!=0)
    8.     {
    9.         i=1<<sizeof(char)*8-1;//i=1<<7
    10.         //bật bit thứ 7 về 1
    11.         Q=Q|i;
    12.     }
    13.     else
    14.     {
    15.         i=1<<sizeof(char)*8-1;
    16.         i=~i;
    17.         //tắt bit thứ 7 về 0
    18.         Q=Q&i;
    19.     }
    20.     i=1<<7;
    21.     i=A&i;
    22.     A=A>>1;
    23.     A=A|i;
    24. }
    tuy nhiên kết quả vẫn lỗi

    - - - Nội dung đã được cập nhật ngày 14-03-2018 lúc 11:04 AM - - -

    code giữ dấu trên hình như sai rồi, dùng lại code đầu, lệnh shift right mặc định đã giữ dấu
    còn về kết quả thì đã đúng theo giá trị nhị phân, sai ở chổ chuyển từ kết quả nhị phân sang số thập phân, có ai biết cách chuyển không?
    và mọi người có ý kiến gì cách dùng kiểu như trên không?
    Đã được chỉnh sửa lần cuối bởi khoaph : 14-03-2018 lúc 11:10 AM.

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