Đã sửa lỗi số học điểm trên vi điều khiển


12

Thông thường chúng ta sử dụng vi điều khiển để làm mọi thứ trong robot của mình, nhưng cần thực hiện một số tính toán theo số thập phân. Sử dụng các biến dấu phẩy động rất chậm, bởi vì một thư viện dấu phẩy động phần mềm được tự động đưa vào (trừ khi bạn có một bộ vi điều khiển cao cấp). Do đó, chúng tôi thường sử dụng số học điểm cố định.

Bất cứ khi nào tôi làm điều này, tôi chỉ cần sử dụng một số nguyên và nhớ vị trí thập phân ở đâu. Tuy nhiên, cần phải cẩn thận để đảm bảo rằng mọi thứ đều nhất quán, đặc biệt khi các phép tính liên quan đến các biến trong đó dấu thập phân ở một vị trí khác.

Tôi đã triển khai hàm atan2 điểm cố định, nhưng vì tôi đang cố gắng nén từng giọt chính xác giới hạn cuối cùng (16 bit), tôi thường sẽ thay đổi định nghĩa về điểm thập phân ở đâu và nó sẽ thay đổi khi tôi điều chỉnh nó. Ngoài ra, tôi sẽ có một số hằng số, như một bảng tra cứu gần đúng, bản thân chúng có một dấu thập phân ngụ ý ở đâu đó.

Tôi muốn biết nếu có một cách tốt hơn. Có thư viện hoặc tập hợp các macro có thể đơn giản hóa việc sử dụng các biến điểm cố định, giúp nhân và chia giữa các biến hỗn hợp dễ dàng hơn và cho phép khai báo các số thập phân hoặc biểu thức không đổi, nhưng tự động chuyển đổi sang biểu diễn điểm cố định mong muốn khi biên dịch thời gian?


1
Tôi nghĩ rằng điều này thực sự tốt hơn cho stackoverflow vì giải pháp này là loại chung chung và không liên quan nhiều đến robot.
Shahbaz

1
@Jakob - Lưu ý rằng cả hai câu hỏi đó đều bị đóng vì không mang tính xây dựng.
Đánh dấu gian hàng

1
Đây là loại điều sẽ làm cho C ++ rất hữu ích cho các hệ thống nhúng. Mẫu sẽ tự động tạo mã chính xác và tối ưu.
Rocketmagnet

1
Tôi có thể xem chức năng atan của bạn không? Tôi đang cố gắng giải quyết vấn đề chuyển đổi từ điểm cố định sang điểm cố định trong nghiên cứu học thuật của mình và tôi sẽ rất vui khi giải quyết vấn đề này.
Joe Hass

1
@ronalchn Các bộ phận của ngôn ngữ Arduino (một micro micro) được triển khai trong C ++. Ngoài ra còn có Thư viện AVR C ++ . Và chủ đề này trên trình biên dịch sẽ sử dụng.
embed.kyle

Câu trả lời:


7

Sẽ thật tuyệt nếu chúng ta có thể nói cho trình biên dịch biết phạm vi và độ chính xác của từng biến đầu vào điểm cố định (có lẽ không có hai điểm nào có điểm radix ở cùng một vị trí) và nó sẽ tự động - vào thời gian biên dịch - sử dụng phạm vi chính xác và các hoạt động chính xác và thay đổi kích thước cho các giá trị trung gian và giá trị cuối cùng trong một loạt các tính toán. Tôi đã nghe tin đồn rằng có thể làm điều đó trong ngôn ngữ lập trình Ada hoặc trong các mẫu C ++.

Than ôi, gần nhất tôi thấy là các thư viện số học điểm cố định yêu cầu bạn, lập trình viên, chọn thủ công biểu diễn chính xác và xác minh thủ công rằng mỗi thao tác duy trì phạm vi và độ chính xác phù hợp. Đôi khi chúng làm cho phép nhân và chia giữa các biến hỗn hợp dễ dàng hơn. Nhu la:


Hầu như chắc chắn có thể làm điều này bằng cách sử dụng các mẫu C ++.
Rocketmagnet

Tôi thực sự đang làm việc trên một cái gì đó giống như bình luận "sẽ rất tuyệt nếu ...". Nó là một plugin cho gcc chuyển đổi mã C dấu phẩy động thành điểm cố định, tối ưu hóa tất cả các vị trí điểm nhị phân trên đường đi. Tôi có một bài viết được gửi đến một tạp chí ACM, và một bài khác đang chuẩn bị. Nếu bạn có mã C cho hàm atan, tôi rất vui lòng cung cấp cho nó một shot ... Tôi có thể trả lại cho bạn mã C sử dụng các biến số nguyên và thực hiện tất cả các công cụ điểm cố định.
Joe Hass

+1 cho câu trả lời đầy đủ hơn nhiều so với của tôi. Tôi đã chỉnh sửa liên kết của mình để bao gồm một liên kết đến một nơi để yêu cầu mã nguồn để giải quyết nhận xét của Mark Booth. Bạn có thể muốn cập nhật liên kết của bạn là tốt. Tôi sẽ tự làm điều đó nhưng một chỉnh sửa được đề xuất đang xếp hàng và đang chặn tôi.
embed.kyle

1
@Rocketmagnet Chắc chắn có thể triển khai các điểm cố định bằng cách sử dụng các mẫu, xem FixedPoints (từ chối trách nhiệm: Tôi đã viết cái này và nó vẫn còn rất 'trẻ').
Pharap

liên kết gcc "a" bị hỏng
Lesto

2

Tôi đã sử dụng Thư viện TI IQMath để triển khai dấu phẩy động ảo trên DSP điểm cố định của chúng.

Thư viện IQmath TMS320C28x của Texas Cụ là tập hợp các hàm toán học có độ chính xác cao và tối ưu hóa cao cho các lập trình viên C / C ++ để chuyển liền mạch thuật toán dấu phẩy động thành mã điểm cố định trên các thiết bị TMS320C28x. Các thói quen này thường được sử dụng trong các ứng dụng thời gian thực chuyên sâu tính toán trong đó tốc độ thực hiện tối ưu và độ chính xác cao là rất quan trọng. Bằng cách sử dụng các thường trình này, bạn có thể đạt được tốc độ thực thi nhanh hơn đáng kể so với mã tương đương được viết bằng ngôn ngữ ANSI C tiêu chuẩn. Ngoài ra, bằng cách cung cấp các chức năng chính xác cao sẵn sàng sử dụng, thư viện TI IQmath có thể rút ngắn đáng kể thời gian phát triển ứng dụng DSP của bạn.

Điều đó sử dụng một số công cụ cụ thể TI nhưng tôi cũng đã sử dụng mã đó làm cơ sở để triển khai toán học dấu phẩy động ảo trên các bộ vi điều khiển khác. Phải mất một chút công việc để chuyển cổng nhưng nó dễ dàng hơn nhiều so với bắt đầu từ đầu.


@downvoter Quan tâm để nhận xét về những gì sai với câu trả lời của tôi?
embedded.kyle

+1: Thư viện này tốt hơn so với những gì anh ta đang sử dụng ("chỉ sử dụng một số nguyên"). Nó không làm mọi thứ mà câu hỏi ban đầu yêu cầu, nhưng tôi nghĩ rằng một câu trả lời như thế này (hữu ích, nhưng không phải là một giải pháp hoàn chỉnh) không xứng đáng với một downvote - trừ khi một giải pháp hoàn chỉnh thực sự tồn tại (mà tôi nghi ngờ trong trường hợp này ).
David Cary

Dường như với tôi rằng một câu trả lời dành riêng cho một loạt các thiết bị và chỉ miễn phí như trong bia chứ không phải trong lời nói được sử dụng hạn chế cho khách truy cập trong tương lai.
Đánh dấu gian hàng

@MarkBooth Tôi đã thay đổi liên kết từ thư viện C28x sang thư viện C64x. Nếu bạn theo liên kết đó, bạn có thể yêu cầu mã nguồn. Bạn cần một công ty hoặc một email của trường đại học để có được quyền truy cập. Vẫn miễn phí như trong bia lời nói. Bạn chỉ cần giơ tay và chờ đợi để được gọi trước khi bạn có thể nói chuyện. Một chút khó chịu, nhưng một khi bạn có mã nguồn, nó có thể được điều chỉnh cho bất kỳ bộ xử lý nào bạn thích.
embed.kyle

Cảm ơn mã nguồn @ embed.kyle chắc chắn tốt hơn chỉ nhị phân, nhưng vẫn ít được sử dụng nếu giấy phép chỉ cho phép bạn sử dụng nó theo những cách hạn chế. Theo trang Thư viện phần mềm C6x , nguồn đó chỉ được phát hành theo Giấy phép thương mại TI , gần như chắc chắn không miễn phí như trong lời nói .
Đánh dấu gian hàng

1

Có một số triển khai (không có thư viện mà tôi biết ngay lập tức) về Thu nhỏ nhị phân (hay còn gọi là B-scale)

Trong phần này, bạn giữ một ghi chú tinh thần (hoặc thậm chí tốt hơn, ghi lại mã ...) về vị trí của dấu thập phân, sử dụng dịch chuyển để di chuyển dấu thập phân lên hoặc xuống.

Tôi đã sử dụng quy mô B trong trình biên dịch chương trình trong các dự án quốc phòng, ngay cả trên các CPU nhỏ nhất để có thể chứng minh tính phù hợp của nó cho bất kỳ điều gì khác ...


Có lẽ một cái gì đó như thế này, nhưng tôi chưa bao giờ thấy nó được gọi là b-scale. Tôi nghĩ đó là điểm cố định - số thập phân không bao giờ nổi bởi vì mặc dù dấu thập phân có thể thay đổi trong quá trình tính toán, bất kỳ một biến nào luôn có dấu thập phân cố định tại một vị trí cụ thể
ronalchn

0

Nếu bạn sử dụng một số nguyên để ghi nhớ "điểm" ở đâu, thì chúng là loại sử dụng số học dấu phẩy động. Điểm cố định, thực sự có điểm cố định .

atancosπ-π

Điều này phụ thuộc vào phạm vi giá trị mà ứng dụng của bạn cần, nhưng bạn có thể muốn hoàn toàn chuyển sang biểu diễn điểm cố định. Đó là, ví dụ, thay vì giữ một số như thế này:

struct num
{
    uint16_t number;
    uint16_t decimal_point;
};

nơi numberlà toàn bộ số và decimal_pointnói nơi dấu thập phân là, bạn có thể lưu nó như thế này:

struct num
{
    uint16_t integer;
    uint16_t fraction;
};

trong đó toàn bộ số là integer.fraction, có cùng mức sử dụng bộ nhớ, phạm vi giá trị cao hơn và nói chung đơn giản hơn để sử dụng.


Trên thực tế lưu trữ dấu thập phân làm cho nó giống như một dấu phẩy động. Thông thường, dấu thập phân được xác định tại thời điểm biên dịch và bạn thay đổi giữa các biểu diễn tùy thuộc vào hoạt động của bạn.
Jakob

Tôi không có nghĩa là nhớ như được lưu trữ trong một biến, tôi có nghĩa là nhớ như trong tôi nhớ cách diễn giải kết quả (bằng cách biết vị trí của dấu thập phân)
ronalchn

@ronalchn, tôi hiểu rồi. Bạn có nghĩa là một cái gì đó như với một #define, phải không? Tôi nghĩ rằng bạn thực sự lưu trữ nó và nó có thể thay đổi dựa trên số lượng lớn hay nhỏ của bạn.
Shahbaz

@ronalchn - bạn đang nghĩ về tỷ lệ B? (xem câu trả lời của tôi)
Andrew
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.