PDA

View Full Version : Một câu hỏi về tính toán với kiểu dữ liệu fractional trong dspic.


uydanh
12-11-2008, 10:27 AM
Hi,
Giả sử em khai báo 3 biến a1, b1, c1 kiểu fractional
3 biến a2, b2, c2 kiểu float.

Lưu giá trị thu được từ ADC (định dạng fractional) vào 2 biến a1 và b1
Thực hiện câu lệnh :

a2=Fract2Float(a1);
b2=Fract2Float(b1);

Như vậy giá trị tương ứng của a1 và b1 nhưng ở dạng Float đã được lưu trong 2 biến a2, b2.
Tiếp theo em thực hiện :

c1=a1*b1;
c2=a2*b2;

Về nguyên tắc thì c1 và c2 mang cùng một giá trị toán học nhưng chỉ được hiểu theo các định dạng số khác nhau. Như vậy thì c2 đang ở dạng Float có bằng với giá trị trả về của hàm Fract2Float(c1) không?
Mong sự giúp đỡ của mọi người.
Cảm ơn rất nhiều.

namqn
12-11-2008, 04:13 PM
Hi,
Giả sử em khai báo 3 biến a1, b1, c1 kiểu fractional
3 biến a2, b2, c2 kiểu float.

Lưu giá trị thu được từ ADC (định dạng fractional) vào 2 biến a1 và b1
Thực hiện câu lệnh :

a2=Fract2Float(a1);
b2=Fract2Float(b1);

Như vậy giá trị tương ứng của a1 và b1 nhưng ở dạng Float đã được lưu trong 2 biến a2, b2.
Tiếp theo em thực hiện :

c1=a1*b1;
c2=a2*b2;

Về nguyên tắc thì c1 và c2 mang cùng một giá trị toán học nhưng chỉ được hiểu theo các định dạng số khác nhau. Như vậy thì c2 đang ở dạng Float có bằng với giá trị trả về của hàm Fract2Float(c1) không?
Mong sự giúp đỡ của mọi người.
Cảm ơn rất nhiều.
Bạn có thể dùng MPLAB SIM để mô phỏng và xem kết quả.

Thân,

uydanh
12-11-2008, 10:25 PM
Cảm ơn anh Nam,
Em đã thử và kết quả là không đúng. Chắc có lẽ vì khi thực hiện 2 phép nhân kiểu Float thì giá trị phải lưu ở dạng 32bits trong khi đó kiểu Float chỉ lưu 16 bits.
Như vậy muốn thực hiện phép nhân 2 số hạng kiểu Fractional, trước tiên phải đổi sang Float trước sau đó mới nhân 2 số Float đó rồi đổi kết quả từ Float sang Fractional lại mới chính xác được.

uydanh
13-11-2008, 04:40 PM
Mình đã tìm trên mạng 1 tài liệu và nó đã chỉ cho cách thức giải quyết vấn đề trên như sau:
- Lấy 2 số fractional a1*a2 được kết quả là 1 số 32 bits.
- Nhân kết quả trên với 0x2
- Kết quả chính xác dạng fractional của phép nhân trên sẽ là 16 bits cao nhất của kết quả sau khi nhân với 0x2.
Ví dụ :

Ta có : a1=0.5 lưu theo dạng fractional là 0x4000
b1=0.75 lưu theo dạng fractional là 0x6000
thực hiện a1 * b1 được kết quả 32bits =0x18000000
ta tiếp tục nhân kết quả đó với 0x2 được 0x30000000
và kết quả fractional của biểu thức a1*b1 là 3000 (chính là 0.375).

Với cách thực hiện này, ta sẽ giảm được "vô số" chu kỳ máy do các lệnh "ngốn" rất nhiều chu kỳ máy Fract2Float và Float2Fract gây ra.

namqn
13-11-2008, 04:54 PM
Nhân hai số ở format 1.15 sẽ được một số ở format 2.30. Nhân 0x2 tức là dịch trái 1 bit sẽ cho kết quả ở format 1.31. Chỉ lấy 16 bit cao nhất sẽ cho kết quả ở format 1.15.

Thân,