Bagaimana angka dengan titik desimal ditangani dalam MCU?

8

Tolong beritahu saya bagaimana MCU menangani angka desimal seperti '23 .3 ',' 3,24 'dll? Bagaimana cara disimpan dalam register memori? Saya tahu bahwa saya harus menggunakan tipe data float ketika menangani angka-angka ini saat pemrograman. Tetapi sebenarnya apa yang terjadi di dalam MCU saat menangani jenis ini. Juga beri tahu saya bagaimana MCU tanpa unit FPU menangani tipe data Float.

0xakhil
sumber

Jawaban:

13

Angka di dalam mikrokontroler biasa tidak memiliki titik desimal sama sekali. Mereka adalah bilangan bulat biner. Tidak ada desimal yang terjadi di dalam mesin. Compiler atau assembler memungkinkan Anda menentukan konstanta seperti itu, tetapi konstanta tersebut dikonversi ke biner sebelum mesin melihatnya.

Namun, Anda dapat memutuskan unit apa pun yang Anda suka untuk nilai integer. Misalnya, Anda ingin mewakili dolar di dalam mikro. Secara alami tidak bisa menghasilkan $ 3,21, tetapi bisa menghasilkan 321 sen. Mikro hanya beroperasi pada nilai 321, tetapi Anda tahu bahwa itu mewakili unit 1/100 dolar.

Itu hanya satu contoh untuk menggambarkan konsep unit sewenang-wenang. Seringkali angka diwakili dengan beberapa bit fraksi biner. Itu sama dengan mengatakan setiap hitungan mewakili nilai 2 -N , di mana N adalah jumlah bit fraksi. Representasi ini disebut "titik tetap". Anda memutuskan di muka berapa resolusi yang Anda butuhkan, dan berpura-pura ada cukup bit di sebelah kanan titik biner yang dibayangkan untuk mendukung resolusi itu. Sebagai contoh, katakanlah Anda perlu mewakili sesuatu untuk setidaknya resolusi 1/100. Dalam hal ini Anda akan menggunakan setidaknya 7 bit pecahan sejak 2 7 = 128. Itu sebenarnya akan memberi Anda resolusi 1/128.

Mesin tidak tahu ini sedang terjadi. Ini akan menambah dan mengurangi angka-angka ini sebagai bilangan bulat biasa, tetapi semuanya masih berhasil. Ini menjadi sedikit rumit ketika Anda mengalikan dan membagi nilai titik tetap. Produk dari dua nilai titik tetap dengan bit pecahan N akan memiliki bit pecahan 2N. Kadang-kadang Anda hanya melacak fakta bahwa nomor baru memiliki bit pecahan 2N, atau kadang-kadang Anda mungkin menggesernya dengan N bit untuk kembali ke representasi yang sama seperti sebelumnya.

Floating point adalah hal yang sama, tetapi jumlah bit fraksi disimpan bersama dengan bagian integer sehingga penyesuaian ini dapat dilakukan saat runtime. Melakukan operasi matematika pada angka floating point dapat mengambil banyak siklus. Perangkat keras Floating point melakukan semua ini untuk Anda sehingga operasi selesai dengan cepat. Namun, manipulasi yang sama dapat dilakukan dalam perangkat lunak juga. Tidak ada alasan Anda tidak dapat menulis subrutin untuk menambahkan dua angka floating point, hanya saja itu akan memakan waktu lebih lama daripada perangkat keras khusus yang melakukan hal yang sama.

Saya telah mendefinisikan format floating point 3-byte untuk PIC 8 bit dan menulis banyak rutin untuk memanipulasi mereka. Mikrokontroler biasanya berurusan dengan nilai dunia nyata dengan presisi 10 atau 12 bit paling banyak. Format floating point saya menggunakan 16 bit presisi, yang cukup baik untuk beberapa perhitungan menengah.

Saya juga memiliki format 32-bit untuk PIC 16 bit. Ini menggunakan satu kata 16-bit untuk mantissa, yang mempercepat perhitungan karena PIC ini dapat beroperasi pada 16 bit pada suatu waktu.

Rutinitas ini termasuk dalam rilis Alat Pengembangan PIC saya . Setelah instalasi, lihat file dengan "fp24" di namanya di direktori SOURCE> PIC, dan "fp32f" di direktori SOURCE> DSPIC.

Olin Lathrop
sumber
Floating Point Standard Ada juga standar IBM yang hanya mengacaukan bias.
NickHalden
4

Aritmatika titik tetap biasanya digunakan untuk melakukan perhitungan fraksional di MCU.

Caranya adalah dengan mengatakan bahwa (misalnya), 16 bit atas uint32_tadalah sebelum titik desimal dan 16 lebih rendah setelahnya, yaitu. bilangan bulat yang disimpan berada di 1/2 ^ 16ths. Dengan beberapa peringatan kecil, aritmatika reguler "hanya berfungsi".

Inilah ikhtisar .

Toby Jaffey
sumber
pilih suara saya untuk tautan "Gambaran Umum" itu.
0xakhil
3

Kecuali jika Anda MCU adalah DSP dengan pengali titik mengambang, semuanya disimpan sebagai angka 16 bit (atau 8 atau 32 tergantung pada platform Anda). Itulah yang sebenarnya diketahui oleh MCU.

Di atas ini, Anda memiliki kode "C" dan kompiler C. Kompiler "tahu" tentang berbagai tipe data seperti char, int, uint's, float, doubles, dan sebagainya.

Representasi float pada perangkat keras yang paling umum adalah dengan format IEEE. Ini memisahkan mantissa dari eksponen dan menggunakan dua kata 16 bit untuk menyimpan informasi. Lihat artikel wiki ini pada format nomor IEEE.

Jadi kompilerlah yang tahu di mana mantissa dan eksponen berada dan menerapkan matematika untuk itu. Ingat belajar tentang logaritma? bagaimana mereka membuat matematika lebih mudah dengan menambahkan kekuatan ketika Anda ingin melipatgandakan? baik kompiler c melakukan sesuatu yang mirip dengan eksponen dan melipatgandakan mantissa untuk menghitung jawabannya. Jadi untuk perkalian floating point kompiler akan membuat kode assembler yang menambahkan eksponen dan melakukan multiplikasi mantissa.

MCU tidak tahu nomornya !!! hanya apa yang diperintahkan untuk dilakukan, memuat memori ke dalam register, menambahkan memori ke register dan mengatur flag carry jika diperlukan, dan seterusnya hingga penggandaan selesai.

Ini adalah kompiler C dan kode Anda yang "abstrak" konsep angka, titik desimal dan sebagainya dari MCU.

Di samping catatan beberapa bahasa juga mendukung tipe data "desimal" yang berguna untuk sistem keuangan - tidak umum pada platform tertanam karena float menggunakan lebih sedikit memori dan berkinerja efisien.

smashtastic
sumber
1

Dengan cara yang sama prosesor full blown tanpa fpu (kebanyakan ARM misalnya) menangani floating point. Dengan fpu perangkat lunak. Ada perpustakaan yang melakukan operasi matematika / bitwise. Jika Anda ingat melakukan penambahan, perkalian, dll di sekolah dasar dengan pensil dan kertas, tidak banyak berubah hari Anda beralih dari bilangan bulat menjadi angka dengan titik desimal. Anda melakukan perhitungan dengan cara yang sama seperti Anda baru saja menyesuaikan angka sehingga titik desimal berbaris sebelum Anda mulai (penjumlahan dan pengurangan) atau setelah Anda selesai (perkalian atau pembagian). Fpus keras dan lunak tidak berbeda, mereka menyesuaikan bit sebelum dan sesudah operasi tetapi operasi pada dasarnya adalah operasi bilangan bulat.

Saya tidak ingat persis di mana menemukannya sekarang, tetapi instrumen texas memiliki dokumen yang sangat baik terkait dengan produk DSP mereka. Ini menjelaskan format titik apung mereka dan menjelaskan bagaimana operasi bekerja. Format mereka tidak memiliki pembulatan dan denormals dan infinity dan diam dan signaling nans seperti IEEE, sehingga jauh lebih mudah untuk dipahami serta secara signifikan lebih cepat daripada format IEEE. Setelah melihat format itu dalam tindakan, Anda telah mengambil langkah pertama menuju format IEEE. Rounding membutuhkan beberapa penjelasan dan pemikiran, tetapi sisanya, dasar-dasar tanda, eksponen, dan mantissa adalah sama.

Sangat mahal, sumber daya bijaksana (memori, flash, siklus cpu) untuk menggunakan perpustakaan float lunak dan saya akan mencegahnya dalam sistem tertanam atau mikrokontroler. 12.3 dan 24.5 cukup mudah untuk dikelola sebagai bilangan bulat 123 dan 245, misalnya, selama Anda ingat atau mungkin jika Anda memastikan semua matematika yang terkait memahami bahwa semua angka dikalikan sepuluh dan jika / ketika Anda menampilkan ke pengguna pada konversi itu Anda menambahkan titik desimal. Menghemat banyak kode dan kinerja. Tentu saja pembagian integer adalah hal yang buruk dengan mikrokontroler dan sistem tertanam serta sebagian besar prosesor tidak memiliki instruksi pembagian, dan itu termasuk pembagian dengan 10 untuk dikonversi menjadi desimal untuk ditampilkan kepada pengguna. Dan jawaban yang sama, pembagian yang Anda dapatkan dari kode C Anda dilakukan dengan menggunakan perpustakaan.

old_timer
sumber
0

Mengapung disimpan dalam format biner 32 bit dan bit 1 adalah untuk menunjukkan jika float adalah angka pos / neg, 8 bit berikutnya adalah eksponen -127, maka ada 23 bit yang merupakan angka lengkap termasuk tempat desimal, yaitu :
1 00010001 00010001000000000000000
Jadi 1 adalah negatif, 8 bit berikutnya menunjukkan eksponen dalam kasus ini:
0001 0001 = 17 (17-127 = -110)
Kemudian mantissa dibagi:
(1+1/4+1/128)2^5

2^5adalah pergerakan desimal ketika float dipindahkan ke biner. Hasilnya kamu kehilangan beberapa digit ketika mengkonversi tetapi mereka dekat. 1.5ex10-110
Saya mungkin telah membuat kesalahan dengan mengikuti orang lain, tetapi ini adalah gagasan umum tentang bagaimana mengapung disimpan dalam memori.

Mike C
sumber
2
Posting ini mungkin berisi jejak informasi, tetapi disembunyikan di beberapa dinding teks pesan chat yang tidak diformat. Stack Exchange bukan Facebook, jadi silakan mencoba menggunakan bahasa yang lebih profesional dan silakan gunakan alat pemformatan yang tersedia untuk membuat informasi terbaca, dimulai dengan paragraf.
pipa