Làm thế nào các số có dấu thập phân được xử lý trong MCU?


8

Vui lòng cho tôi biết làm thế nào để MCU xử lý các số thập phân như '23 .3 ',' 3.24 ', v.v? Làm thế nào nó được lưu trữ trong một thanh ghi bộ nhớ? Tôi biết rằng tôi phải sử dụng kiểu dữ liệu float khi xử lý các số này trong khi lập trình. Nhưng thực sự những gì đang xảy ra bên trong MCU trong khi xử lý các loại này. Cũng cho tôi biết làm thế nào để MCU không có đơn vị FPU xử lý kiểu dữ liệu Float.

Câu trả lời:


13

Các số bên trong bộ vi điều khiển thông thường hoàn toàn không có dấu thập phân. Chúng là số nguyên nhị phân. Không có số thập phân đang diễn ra bên trong máy. Trình biên dịch hoặc trình biên dịch có thể cho phép bạn chỉ định các hằng số theo cách đó, nhưng chúng được chuyển đổi thành nhị phân trước khi máy nhìn thấy chúng.

Tuy nhiên, bạn có thể quyết định bất kỳ đơn vị nào bạn thích cho các giá trị số nguyên. Ví dụ: giả sử bạn muốn đại diện cho đô la trong một vi mô. Nó thực sự không thể làm $ 3,21, nhưng nó có thể làm được 321 xu. Micro chỉ hoạt động trên giá trị 321, nhưng bạn biết rằng nó đại diện cho các đơn vị 1/100 đô la.

Đó chỉ là một ví dụ để minh họa khái niệm các đơn vị tùy ý. Thông thường các số được biểu diễn với một số bit phân số nhị phân. Điều đó giống như nói mỗi số đếm đại diện cho một giá trị 2 -N , trong đó N là số bit phân số. Đại diện này được gọi là "điểm cố định". Bạn quyết định trước mức độ phân giải bạn cần và giả vờ có đủ bit ở bên phải của điểm nhị phân tưởng tượng để hỗ trợ độ phân giải đó. Ví dụ: giả sử bạn cần đại diện cho một cái gì đó với độ phân giải ít nhất là 1/100. Trong trường hợp đó, bạn sẽ sử dụng ít nhất 7 bit phân số kể từ 2 7 = 128. Điều đó thực sự sẽ cung cấp cho bạn độ phân giải 1/128.

Máy không có ý tưởng này đang xảy ra. Nó sẽ cộng và trừ các số này dưới dạng số nguyên thông thường, nhưng mọi thứ vẫn hoạt động. Sẽ có một chút khó khăn khi bạn nhân và chia các giá trị điểm cố định. Tích của hai giá trị điểm cố định với các bit phân số N sẽ có các bit phân số 2N. Đôi khi bạn chỉ cần theo dõi thực tế là số mới có các bit phân số 2N hoặc đôi khi bạn có thể dịch chuyển nó đúng theo N bit để quay lại biểu diễn giống như trước.

Điểm nổi là điều tương tự, nhưng số lượng bit phân số được lưu trữ cùng với phần nguyên để điều chỉnh này có thể được thực hiện khi chạy. Thực hiện các phép toán trên các số dấu phẩy động có thể mất một loạt các chu kỳ. Phần cứng dấu phẩy động làm tất cả điều này cho bạn để các hoạt động hoàn thành nhanh chóng. Tuy nhiên, các thao tác tương tự cũng có thể được thực hiện trong phần mềm. Không có lý do gì bạn không thể viết chương trình con để thêm hai số dấu phẩy động, chỉ là nó sẽ mất nhiều thời gian hơn so với phần cứng chuyên dụng làm cùng một việc.

Tôi đã định nghĩa một định dạng dấu phẩy động 3 byte cho PIC 8 bit và viết một loạt các thói quen để thao tác chúng. Vi điều khiển thường xử lý các giá trị trong thế giới thực với độ chính xác tối đa 10 hoặc 12 bit. Định dạng dấu phẩy động của tôi sử dụng 16 bit chính xác, đủ tốt cho một số tính toán trung gian.

Tôi cũng có định dạng 32 bit cho PIC 16 bit. Điều này sử dụng một từ 16 bit cho mantissa, giúp tăng tốc các phép tính vì các PIC này có thể hoạt động trên 16 bit cùng một lúc.

Những thói quen này được bao gồm trong bản phát hành Công cụ phát triển PIC của tôi . Sau khi cài đặt, hãy xem các tệp có "fp24" trong tên của chúng trong thư mục SOURCE> PIC và "fp32f" trong thư mục SOURCE> DSPIC.


Tiêu chuẩn dấu phẩy động Ngoài ra còn có một tiêu chuẩn IBM chỉ xoay quanh sai lệch.
NickHalden

4

Số học điểm cố định thường được sử dụng để thực hiện các phép tính phân số trong MCU.

Thủ thuật là để nói rằng (ví dụ), 16 bit trên của a uint32_tnằm trước dấu thập phân và 16 dưới là sau, tức là. số nguyên được lưu trữ là trong 1/2 ^ 16th. Với một số cảnh báo nhỏ, số học thông thường "chỉ hoạt động".

Đây là một cái nhìn tổng quan .


bỏ phiếu từ tôi cho liên kết "Tổng quan".
0xakhil

3

Trừ khi bạn MCU là một DSP với hệ số nhân dấu phẩy động, mọi thứ được lưu trữ dưới dạng số 16 bit (hoặc 8 hoặc 32 tùy thuộc vào nền tảng của bạn). Đó là tất cả những gì MCU thực tế biết về.

Ở trên này bạn có mã "C" và trình biên dịch C của bạn. Trình biên dịch "biết" về các loại dữ liệu khác nhau như char, int's, uint's, float, double, v.v.

Đại diện phổ biến nhất của phao trên phần cứng là với định dạng IEEE. Điều này phân tách lớp phủ từ số mũ và sử dụng hai từ 16 bit để lưu trữ thông tin. Kiểm tra bài viết wiki này về các định dạng số IEEE.

Vì vậy, nó là trình biên dịch biết vị trí của số mũ và số mũ và áp dụng các phép toán cho nó. Remeber học về logarit? Làm thế nào họ làm cho toán học dễ dàng hơn bằng cách thêm sức mạnh khi bạn muốn nhiều? cũng là trình biên dịch c làm một cái gì đó tương tự với các kết nối và nhân hệ số để tính toán câu trả lời. Vì vậy, đối với phép nhân dấu phẩy động, trình biên dịch sẽ tạo mã trình biên dịch mã bổ sung các số mũ và thực hiện phép nhân của mantissa.

MCU không biết gì về số lượng !!! chỉ cần những gì nó được thực hiện, tải một bộ nhớ vào một thanh ghi, thêm một bộ nhớ vào thanh ghi và đặt cờ mang theo nếu cần, và cứ thế cho đến khi phép nhân hoàn thành.

Chính trình biên dịch C và mã của bạn "tóm tắt" khái niệm số, dấu thập phân, v.v. từ MCU.

Mặt khác, một số ngôn ngữ cũng hỗ trợ kiểu dữ liệu "thập phân" rất hữu ích cho các hệ thống tài chính - không phổ biến trên các nền tảng nhúng vì phao sử dụng ít bộ nhớ hơn và hoạt động hiệu quả.


1

Cùng một cách xử lý toàn bộ bộ xử lý thổi mà không có fpu (ví dụ như hầu hết các ARM) xử lý điểm nổi. Với một phần mềm fpu. Có một thư viện thực hiện các phép toán / bitwise. Nếu bạn nhớ làm thêm, nhân, v.v. ở trường tiểu học bằng bút chì và giấy, không có nhiều thay đổi trong ngày bạn đi từ số nguyên sang số có dấu thập phân. Bạn đã làm toán giống như cách bạn chỉ cần điều chỉnh các số sao cho các dấu thập phân xếp thành hàng trước khi bạn bắt đầu (cộng và trừ) hoặc sau khi bạn hoàn thành (nhân hoặc chia). Fpus cứng và mềm không khác nhau, họ điều chỉnh các bit trước và sau khi hoạt động nhưng hoạt động về cơ bản là hoạt động toàn bộ số.

Tôi không nhớ chính xác nơi tìm nó bây giờ, nhưng các nhạc cụ texas có một tài liệu rất tốt liên quan đến các sản phẩm DSP của họ. Nó giải thích định dạng dấu phẩy động của chúng và đi xa đến mức giải thích các hoạt động như thế nào. Định dạng của chúng không có làm tròn và biến dạng và vô cực và không có tín hiệu và im lặng như IEEE, do đó dễ hiểu hơn cũng như nhanh hơn đáng kể so với định dạng của IEEE. Khi thấy định dạng đó hoạt động, bạn đã thực hiện bước đầu tiên đối với định dạng IEEE. Làm tròn có một số giải thích và suy nghĩ, nhưng phần còn lại của nó, những điều cơ bản của dấu hiệu, số mũ và mantissa là như nhau.

Nó rất tốn kém, khôn ngoan về tài nguyên (bộ nhớ, flash, chu kỳ cpu) để sử dụng các thư viện float mềm và tôi sẽ không khuyến khích nó trong một hệ thống nhúng hoặc vi điều khiển. Ví dụ, 12.3 và 24.5 khá dễ quản lý như các số nguyên 123 và 245, miễn là bạn nhớ hoặc có lẽ nếu bạn chắc chắn rằng tất cả toán học liên quan của bạn hiểu rằng các số được nhân với mười và nếu / khi bạn hiển thị cho một người dùng trên chuyển đổi đó bạn thêm dấu thập phân. Tiết kiệm hàng tấn mã và hiệu suất. Tất nhiên việc chia số nguyên là một điều tồi tệ với vi điều khiển và hệ thống nhúng cũng như hầu hết các bộ xử lý không có lệnh chia và bao gồm phép chia cho 10 để chuyển thành số thập phân để hiển thị cho người dùng. Và cùng một câu trả lời, việc phân chia mà bạn nhận được từ mã C của bạn được thực hiện bằng thư viện.


0

Phao được lưu trữ ở định dạng nhị phân 32 bit và bit thứ 1 là để cho biết số float là số pos / neg, 8 bit tiếp theo là số mũ -127, sau đó có 23 bit là số hoàn chỉnh bao gồm cả số thập phân, nghĩa là :
1 00010001 00010001000000000000000
Vì vậy, 1 là âm, 8 bit tiếp theo là để chỉ ra số mũ trong trường hợp này:
0001 0001 = 17 (17-127 = -110)
Sau đó, phần tử được chia:
(1+1/4+1/128)2^5

2^5là chuyển động của vị trí thập phân khi float được chuyển sang nhị phân. Kết quả Yhe không mất một số chữ số khi chuyển đổi nhưng chúng gần. 1.5ex10-110
Tôi có thể đã mắc lỗi sau những người khác, nhưng đây là ý tưởng chung về cách lưu trôi trong bộ nhớ.


2
Bài đăng này có thể chứa dấu vết thông tin, nhưng nó bị ẩn trong một số thông điệp trò chuyện không được định dạng trên tường. Stack Exchange không phải là Facebook, vì vậy hãy thử sử dụng ngôn ngữ chuyên nghiệp hơn và vui lòng sử dụng các công cụ định dạng có sẵn để làm cho thông tin dễ đọc, bắt đầu bằng các đoạn văn.
ống
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.