Top Ad unit 728 × 90

Latest news

recent

Phương pháp chuyển đổi miền số thực (Floating Point) sang số nguyên (Integer)

Khả năng xử lý số thực hay số chấm động là một trong những tác vụ thể hiện sức mạnh của các CPU ngày nay. Tuy nhiên với các thiết bị nhúng, nhỏ, hỗ trợ tính toán yếu thì đây vẫn là một vấn đề. Việc tích hợp tính toán trên miền số thực ở mức phần cứng gây ra sự tiêu hao năng lượng lớn, giá thành sản phẩm cao nên trong nhiều trường hợp nó vẫn không được sử dụng.
Trong khi đó, có rất nhiều các thuật toán, các xử lý thông minh dựa trên nền thống kê, phân tích dữ liệu cần dùng số thực như một sự tối ưu do đây là kiểu dữ liệu có dải giá trị rộng, độ liên tục cao, có thể biểu diễn dữ liệu trong những tình huống khắt khe với độ chính xác tốt nhất. Vậy phải làm sao đây khi mà phần cứng chỉ hỗ trợ số nguyên mà thuật toán thì được triển khai trong miền số thực. Để trả lời câu hỏi này mà nhu cầu của việc chuyển đổi miền giá trị xuất hiện. Có hai dạng biểu diễn số thực trong môi trường hỗ trợ số nguyên, một là dùng số nguyên thuần túy, hai là dựa trên kiến trúc số nguyên nhưng áp dụng logic số thực để mô phỏng cho giá trị thực (đây chính là nguyên tắc của Fixed Point). Xét về khía cạnh phương thức chuyển đổi, chúng ta có 2 con đường, một là để cho trình biên dịch có hỗ trợ tự động chuyển đổi từ số thực sang fixed point tự xử, có nghĩa là chúng ta cứ viết chương trình dùng số thực, khi biên dịch trình biên dịch tự động chuyển đổi sang fixed point mà đã được hỗ trợ bên trong bản thân ứng dụng nhân của thiết bị ( dưới hình thức các thư viện tích hợp). Phương pháp này chỉ dùng cho fixed point chứ không dùng số nguyên thuần túy. Hai là ta sẽ chuyển đổi bằng tay trong quá trình thực hiện chương trình, mã nguồn số thực sẽ được thay thế bằng số nguyên hoặc kiểu dữ liệu fixed point. Trong trường hợp lập trình bằng kiểu fixed point chúng ta phải định nghĩa kiểu dữ liệu mới, xây dựng các hàm tính tóan đặc thù (trong phương pháp thứ nhất  cái này đã được giải quyết nhờ sự bắt tay, thông đồng giữa thiết bị và trình biên dịch). Ở phương pháp thứ nhất vì trình biên dịch không đủ thông minh như chúng ta nên vấn đề gặp phải đó là tối ưu hóa tính tóan. Ở phương pháp thứ hai đòi hỏi bạn phải hiểu thấu đáo thuật tóan, giám sát được vấn đề tràn giá trị, sai số, ... trong quá trình chuyển đổi. Dưới đây chúng ta sẽ đi vào chi tiết phương pháp thứ 2  trong tình huống  dùng số nguyên (dùng fixed point sẽ được trình bày kỉ trong bài viết tới), do phương pháp một chỉ là vấn đề của cấu hình và không giống nhau giữa các trình biên dịch cũng như thiết bị nên sẽ không được đề cập.
  • Ước lượng khoảng giá trị của biến và xác định giới hạn sai số cho phép:
    ví dụ trong ứng dụng của chúng ta có hai biến số thực là f1 và f2. Thông qua khảo sát ta xác định giá trị của f1 trong khoảng [1,123, 8,234], giá trị của f2 trong khoảng [0.123457, 0.854567]  
  • Ấn định thông số shift thích hợp cho các biến:
    trong trường hợp f1 ở trên nếu ta shift nó đi 10 bit thì sẽ đảm bảo một sai số là 0: f1' = f1 << 10
    (khử hoàn toàn phần thập phân), tuy nhiên vì f1 có thể được sử dụng trong các công thức khác nhau, việc shift giá trị của nó sẽ ảnh hướng tới giá trị các biến khác. Để đảm bảo tạo ra một phép biến đổi tổng thể không thay đổi "form" hay "sharp" thì các biến liên quan tới f1 cũng phải được shift tương ứng. Tuy nhiên trong trường hợp này rất có thể xảy ra tình huống các biến liên quan phải shift một khoản quá lớn dẫn đến tràn, do đó nhiều khi ta phải chọn thông số shift cho f1 không phải là 10 mà phải nhỏ hơn và chấp nhận sai số. Đây là một qua trình cân bằng giữa sai số và tràn giá trị trong tính toán chuyển đổi.
  • Thực hiện việc chuẩn hóa công thức để tạo ra phép biến đổi thay đổi giá trị chứ không thay đổi "sharp":
    Quá trình này thực chất đã được xem xét trong bước 2 :), ở đây chỉ là bước thiết lập mà thôi.
    Ví dụ:
    - chương trình gốc dùng số thực ta có: float f1 = 1,234; float f2= 0,123456;
    f1 = f2 * 3 + 2;
    - chương trình sau chuyển đổi:
                    int f1' = 1264; // ~ 1,234 * 2^10
                    int f2' = 129453; // ~ 0,123456*2^20
                    f1' = (f2' * 3 + 2 << 20) >> 10; // "sharp" giữ nguyên do: f1' luôn bằng f1 * 2^10
Hy vọng với sự trình bày sơ lược như trên sẽ giúp các bạn có cái nhìn rỏ ràng hơn về kiểu dữ liệu, xử lý số trong quá trình triển khai thuật toán, đồng thời cũng vạch ra một hướng đi trong việc tối ưu thuật toán trên các bộ xử lý khác nhau.


Binh Nguyen - Bioz
Phương pháp chuyển đổi miền số thực (Floating Point) sang số nguyên (Integer) Reviewed by Bioz Nguyen on 7:46:00 PM Rating: 5
All Rights Reserved by IEEV © 2009 - 2016
Powered By Blogger, Designed by Sweetheme

Contact Form

Name

Email *

Message *

Powered by Blogger.