Simulinkでの single型の扱いについて

Simulinkで、定数 0.01の出力型をSingleとし、Gainブロックで1000倍すると、出力が10 となります。
Single型での0.01の実際の値は、0.009999... で、1000倍した時に誤差がなくなってしまうのはなぜでしょうか

5 Kommentare

Atsushi Ueno
Atsushi Ueno am 23 Nov. 2021
Verschoben: Atsushi Ueno am 17 Aug. 2022
MATLABに限らず、コンピュータで表現する数値についての話になります。
単精度(single)の浮動小数点数は、符号1bit、仮数部8bit、指数部23bitの計32bitで表現されます。詳細はリンク先に譲りますが、小数点数を整数と小数に分けて考えます。整数部に10進数表現と2進数表現の誤差はありませんが、小数部には10進数表現と2進数表現の誤差があります。
上記リンク先は、入力した数値について解説してくれるのでとても分かり易いです。「10進数、32bit(single)、0.01」を入力して変換し、その後の解説を読めば理解できます。
katsunori shigematsu
katsunori shigematsu am 24 Nov. 2021
Verschoben: Atsushi Ueno am 17 Aug. 2022
回答ありがとうございます。
ただ、質問の意図としては、
例えば 0.01 のConstantブロックの出力型をSingleとし、これを1000回足すと、10にはなりません(桁は小さいですが端数が出ます)。
ところが、
0.01 のConstantブロックの出力型をSingleとし、これを1000倍すると、誤差なく10 が出力されます。
Single型の2進数表現の問題なのは理解しますが、1000倍した際に誤差なく(表示されないくらい微小な誤差扱いになるのかもしれませんが) 10となってしまう理由が分かりません。
Atsushi Ueno
Atsushi Ueno am 25 Nov. 2021
Verschoben: Atsushi Ueno am 17 Aug. 2022
Simulinkに限らず、single(IEEE 754での単精度浮動小数点数)の演算により生じる誤差の為です。
下図は、0.01に0.01を2回足して0.03にしてみた結果です。
32bitの浮動小数点数で0.01を表現すると0.0099999904632568359375となります。ならば0.01を1000回足した値は9.9999904632568359375になるかというとそれは違います。0.01+0.01=0.02は2進数の仮数部が全く同じままで正確に2倍の値を保つ事が出来ますが、0.02+0.01=0.03は仮数部の値がすっかり様変わりしてしまいます。つまり足し算を繰り返す度に「演算による誤差(2進数の分解能によるズレ)」が累積されます。
下図は、0.01に1000を掛けて10にしてみた結果です。
一方浮動小数点数の乗算(1000倍)の場合は、仮数部同士を2進数で乗算した結果に指数部同士の桁合わせを行った結果、10ぴったりの値になります。0.01を2進数で表現する為に23桁フルに使っていた情報は乗算結果オーバーフローした方に行ってしまい、その結果殆ど全てが捨てられてしまっています。
Atsushi Ueno
Atsushi Ueno am 25 Nov. 2021
Verschoben: Atsushi Ueno am 17 Aug. 2022
余談ですが:
浮動小数点数演算は、規格(IEEE754など)、処理系、CPUや他ハードウェアの違いに依存します。全く同じソフトウェアで演算をしても、処理系やハードウェアが異なると演算誤差が異なる場合があります。

Melden Sie sich an, um zu kommentieren.

Antworten (0)

Produkte

Version

R2016b

Tags

Gefragt:

am 23 Nov. 2021

Verschoben:

am 17 Aug. 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!