ab.com コミュニティ https://www.activebasic.com/forum/ |
|
浮動小数点型(Single,Double)の演算 https://www.activebasic.com/forum/viewtopic.php?t=1823 |
ページ 1 / 1 |
作成者: | KICO [ 2007年2月21日(水) 12:39 ] |
記事の件名: | 浮動小数点型(Single,Double)の演算 |
何時も、お世話に成っています。 浮動小数点型の演算結果がおかしいです。(全バージョン) 例えば、下記のようにiが0からだと"5.99999999999999"に 1の場合は"6.19999999999999"と云うように正しい値が得られません。 Dim i As Double For i=0 to 10 Step 0.1 If Len(Str$(i))>3 Then debug: i=10 next 宜しくお願いします。 |
作成者: | イグトランス [ 2007年2月21日(水) 14:54 ] |
記事の件名: | |
それはCPUの都合上の問題でABの問題ではありません。 x86を始めとした現存する多くのCPUでは浮動小数点数も二進法で表現します。 十進法では有限小数だった数でも二進法で表現すると無限小数となることがあり, 無限を扱えない現代のコンピュータでは適当なところで桁を捨てるため誤差を生じることとなります。 そのためそのように一見正しくないような結果となるのです。 通常は画面へ表示するなど文字列として表現する際に,適当な桁数で丸めるなどして 下のほうの桁を見せないといった工夫によって問題を隠し,それが対処法としては最も簡単です。 もし厳密さを求めるとしたら十進法主体で表現すれば良いのです。 二進法の浮動小数点数は通常±x * 2 ^ nという形で表現され,メモリやレジスタ上ではxとnと符号を記録しています。 しかし±x * 10 ^ nの形式で演算すれば,今回の例のような十進法と二進法の違いによる誤差はだいぶ防げるはずです。 あるいはx / yというような有理数(分数)として演算するという手もあります。 いずれにしても自分でそのようなコードを書かなければなりませんし,その他の種類の誤差の発生にも気を付けなければ台無しです。 |
作成者: | KICO [ 2007年2月21日(水) 18:58 ] |
記事の件名: | 浮動小数点型(Single,Double)の演算 |
イグトランス (egtra)様、何時も ありがとう御座います。 引用: それはCPUの都合上の問題でABの問題ではありません。
バグではなかったのですか、失礼しました。でも何故、例のコードの場合iの開始値が違うと演算結果も違ってくるのでしょうか? 宜しくお願いします。 |
作成者: | イグトランス [ 2007年2月21日(水) 21:31 ] |
記事の件名: | |
それはやはりおよそ開始値によって誤差の溜まり方が変わってくるということもあるでしょう。 またABのStr$が浮動小数点数を文字列にする際の処理も関係してきます。 ABのStr$は上から約15桁を文字列にしますが,それ以下の桁は四捨五入します。 値によってはこれで誤差が先程書いたように誤魔化される場合が生じるのです。 誤差が誤魔化せないほどたまってくると四捨五入の網を潜り抜け.999のように目に見えてしまうのです(これは多少不正確な例えですが)。 なお元のコードでは0.1が2を基数とした指数表記で循環小数になってしまう数です。 整数は浮動小数点数でも正確に表現できる数です。 |
作成者: | KICO [ 2007年2月21日(水) 22:18 ] |
記事の件名: | 浮動小数点型(Single,Double)の演算 |
引用: >それはやはりおよそ開始値によって誤差の溜まり方が変わってくるということもあるでしょう。
その解決法は、無いのでしょうか?引用: >またABのStr$が浮動小数点数を文字列にする際の処理も関係してきます。
Str$、Valに関しては、浮動小数点型に対応出来るよう関数を作ったので、その辺は>ABのStr$は上から約15桁を文字列にしますが,それ以下の桁は四捨五入します。 問題は無いと思います。 宜しくお願いします。 |
作成者: | OverTaker [ 2007年2月21日(水) 22:46 ] |
記事の件名: | |
引用: その解決法は、無いのでしょうか?
その解決方法ではないのですが、イグトランスさんが仰ったように、十進数で計算するのが最も簡単な回避方法だと思います。コード: Dim i Dobule For i = 0 To 10 Step 0.1 Print i Next例えば、このようなものは、下のように10倍した値で計算し、最後に10で割れば、結果的には変わりのないことです。 コード: Dim i Long For i = 0 To 100 Step 1 Print i / 10 Next的外れな回答でしたら申し訳ありません。 |
作成者: | KICO [ 2007年2月22日(木) 18:35 ] |
記事の件名: | 浮動小数点型(Single,Double)の演算 |
OverTaker様、何時も ありがとう御座います。 引用: >例えば、このようなものは、下のように10倍した値で計算し、最後に10で割れば、結果的には変わりのないことです。
いいえ、回避方法としては決して的外れな回答ではないと思います。>Code: >Dim i Long >For i = 0 To 100 Step 1 > Print i / 10 >Next >的外れな回答でしたら申し訳ありません。 ただ、倍した値がLongの有効範囲の10億位を超える値は扱えないと云うように 根本的な解決方法ではないと思うのですが? 宜しくお願いします。 |
作成者: | イグトランス [ 2007年2月22日(木) 19:29 ] |
記事の件名: | |
それだったら,iの型をInt64にしたりDoubleにしたりすればどうでしょうか? 元々Doubleで計算していたものならこれで桁数などは大体間に合うと思います。 |
作成者: | KICO [ 2007年2月22日(木) 23:32 ] |
記事の件名: | 浮動小数点型(Single,Double)の演算 |
イグトランス (egtra)様、OverTaker様、 ありがとう御座いました。 Int64が有りましたね、Ver3.13でしていたものですから気が付きませんでした。 実数を扱う場合は、目的に合った回避方法で対処するしかない様ですネ。 途中から質問版に成りましたが、お答え頂きましてありがとう御座いました。 また質問の際は、宜しくお願いします。 |
ページ 1 / 1 | 全ての表示時間は UTC+09:00 です |
Powered by phpBB® Forum Software © phpBB Limited https://www.phpbb.com/ |