小数点のある数値はMCUでどのように処理されますか?


8

MCUが「23.3」、「3.24」などの10進数をどのように処理するか教えてください。メモリレジスタにどのように格納されますか?プログラミング中にこれらの数値を処理するときは、floatデータ型を使用する必要があることを知っています。しかし実際には、これらのタイプを処理しているときにMCUの内部で何が起こっているのか。FPUユニットのないMCUがFloatデータ型をどのように処理するかについても教えてください。

回答:


13

一般的なマイクロコントローラー内の数値には小数点がありません。これらは2進整数です。マシン内で起こっている小数はありません。コンパイラまたはアセンブラでは、定数をそのように指定できますが、マシンで認識される前にバイナリに変換されます。

ただし、整数値の単位は自由に決めることができます。たとえば、マイクロ内でドルを表現したいとします。本来は$ 3.21はできませんが、321セントは可能です。マイクロは単に値321で動作していますが、1/100ドルの単位を表していることがわかります。

これは、任意の単位の概念を説明するための1つの例にすぎません。多くの場合、数値はいくつかの2進小数ビットで表されます。これは、各カウントが2 -Nの値を表すことと同じです。ここで、Nは小数ビットの数です。この表現は「固定小数点」と呼ばれます。必要な解像度を前もって決定し、想像上の2進小数点の右側にその解像度をサポートするのに十分なビットがあると仮定します。たとえば、少なくとも1/100の解像度で表現する必要があるとします。その場合、2 7 = 128なので、少なくとも7つの小数ビットを使用します。実際には、1/128の解像度になります。

マシンはこれが起こっていることを知りません。これらの数値を通常の整数として加算および減算しますが、すべてうまくいきます。固定小数点値を乗算およ​​び除算する場合、少し注意が必要です。2つの固定小数点値とN個の小数ビットの積は、2N個の小数ビットを持ちます。新しい数値の端数が2Nビットであるという事実を追跡する場合もあれば、Nビットだけ右にシフトして以前と同じ表現に戻す場合もあります。

浮動小数点も同じですが、小数ビットの数は整数部分とともに保存されるため、この調整は実行時に行うことができます。浮動小数点数に対して数学演算を実行すると、大量のサイクルがかかる場合があります。浮動小数点ハードウェアがこれをすべて実行するので、操作が迅速に完了します。ただし、同じ操作をソフトウェアでも実行できます。2つの浮動小数点数を追加するサブルーチンを作成できない理由はありません。同じことを行う専用のハードウェアよりもはるかに時間がかかるだけです。

8ビットPICの3バイトの浮動小数点形式を定義し、それらを操作するための一連のルーチンを記述しました。マイクロコントローラは通常、最大10または12ビットの精度で実際の値を処理します。私の浮動小数点形式は16ビットの精度を使用しており、これはいくつかの中間計算には十分です。

16ビットPIC用の32ビット形式もあります。これは仮数に1つの16ビットワードを使用します。これらのPICは一度に16ビットで動作できるため、計算が高速化されます。

これらのルーチンは、PIC開発ツールのリリースに含まれています。インストール後、SOURCE> PICディレクトリの名前に "fp24"が含まれているファイルと、SOURCE> DSPICディレクトリの "fp32f"が含まれているファイルを確認します。


浮動小数点標準バイアスをいじったばかりのIBM標準もあります。
NickHalden、2011年

4

固定小数点演算は通常、MCUで分数計算を実行するために使用されます。

トリックは、(例えば)aの上位16ビットがuint32_t小数点の前にあり、下位16 ビットが後にある、と言うことです。格納される整数は1/2 ^ 16分の1です。いくつかの小さな注意点がありますが、通常の算術は「うまくいきます」。

こちらが概要です。


その「概要」リンクに対する私からの賛成票。
0xakhil

3

MCUが浮動小数点乗算器を備えたDSPでない限り、すべてが16ビット(またはプラットフォームによっては8または32)の数値として格納されます。それが実際のMCUが知っているすべてです。

この上に「C」コードとCコンパイラがあります。コンパイラーは、char、int、uint、float、doubleなどのさまざまなデータ型について「認識」しています。

ハードウェア上の浮動小数点の最も一般的な表現は、IEEE形式です。これは仮数を指数から分離し、2つの16ビットワードを使用して情報を格納します。IEEEの数値形式に関するこのWikiの記事を確認してください。

したがって、仮数と指数がどこにあるかを認識し、それに数学を適用するのはコンパイラーです。対数について学ぶことを覚えていますか?複数にしたいときにパワーを追加することで、それらはどのようにして数学をより簡単にしましたか?まあcコンパイラは指数と同様のことを行い、仮数を掛けて答えを計算します。したがって、浮動小数点乗算の場合、コンパイラは指数を追加して仮数の乗算を実行するアセンブラコードを作成します。

MCUは番号を何も知りません!!! 指示どおりに、メモリをレジスタにロードし、メモリをレジスタに追加し、必要に応じてキャリーフラグを設定し、乗算が完了するまで続けます。

MCUから数値、小数点などの概念を「抽象化」するのは、Cコンパイラとコードです。

余談ですが、一部の言語では、金融システムに役立つ「10進数」データ型もサポートされています。組み込みプラットフォームでは、フロートのメモリ使用量が少なく効率的に実行されるため、一般的ではありません。


1

fpuを使用しないフルブロープロセッサ(ほとんどのARMなど)が浮動小数点を処理するのと同じ方法です。ソフトウェアfpuを使用。数学/ビット演算を実行するライブラリがあります。小学校で鉛筆と紙を使って足し算や掛け算などをしたことを覚えていれば、整数から小数点付きの数字に変わった日はそれほど変わりません。計算は、開始する前(加算と減算)または終了した後(乗算または除算)に小数点が並ぶように数値を調整する必要があるのと同じ方法で行いました。ハードとソフトのfpusには違いがなく、演算の前後でビットを調整しますが、演算は基本的に整数演算です。

今どこにあるのか正確には覚えていませんが、テキサスインスツルメンツにはDSP製品に関する非常に優れたドキュメントがありました。浮動小数点形式について説明し、操作がどのように機能するかを説明しました。それらの形式には、IEEEのような丸めと非正規化、無限大、静粛性、信号のナンスがないため、IEEE形式よりもはるかに理解しやすく、はるかに高速です。実際にそのフォーマットを確認したら、IEEEフォーマットへの第一歩を踏み出しました。丸めには説明と考えが必要ですが、残りの部分、符号、指数、および仮数の基本は同じです。

ソフトフロートライブラリを使用するのは非常にコストがかかり、リソースの観点から(メモリ、フラッシュ、CPUサイクル)、組み込みシステムやマイクロコントローラーでは使用しないでください。12.3と24.5は、たとえば、覚えている限り、または関連付けられているすべての数学で数値がすべて10倍されていることを理解している場合、または表示する場合は整数123および245として管理するのは非常に簡単です。その変換でユーザーは小数点を追加します。大量のコードとパフォーマンスを節約します。もちろん、整数除算はマイクロコントローラーや組み込みシステムでは悪いことであり、ほとんどのプロセッサーには除算命令がありません。これには10で除算して10進数に変換してユーザーに表示することが含まれます。同じ答え、Cコードから得られる除算はライブラリを使用して行われます。


0

フロートはバイナリの32ビット形式で格納され、最初のビットはフロートがpos / neg数であるかどうかを示すためのもので、次の8ビットは指数-127であり、小数点以下を含む完全な数である23ビットがあります。 :
1 00010001 00010001000000000000000
したがって、1は負であることを示します。次の8ビットは、この場合の指数を示します。
0001 0001 = 17 (17-127 = -110)
次に、仮数が除算されます。
(1+1/4+1/128)2^5

2^5フロートがバイナリに移動したときの小数点以下の動きでした。結果は変換時にいくつかの数字を失うが、それらは近い。1.5ex10-110
私は他の人に続いてエラーを起こしたかもしれませんが、これはフロートがメモリに保存される方法の一般的な考え方です。


2
この投稿には情報の痕跡が含まれている可能性がありますが、フォーマットされていないチャットメッセージのテキストの壁に隠れています。Stack ExchangeはFacebookではないので、より専門的な言語を使用してみてください。段落から始めて、情報を読みやすくするために用意されているフォーマットツール使用してください
パイプ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.