ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月28日(木) 22:05

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 5 件の記事 ] 
作成者 メッセージ
 記事の件名: Singleの除算
投稿記事Posted: 2008年5月05日(月) 22:00 
はじめまして。

次のことを質問させて下さい。

#prompt

dim a,b,c as single

a=2.4
b=2.4
c=(a+b)/2.0

print c

while Inkey$()=""
wend

end

とすると、答えが.2.400000095・・・
となり、2.4になりません。

print (a+b)/2.0

とすると、答えは、2.4になり、正常です。

もしよろしければ、原因と対処方法を教えて
頂けませんか。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2008年5月06日(火) 00:39 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
お住まい: 埼玉県東松山市
それはcだけがsingle型になっているためです。バグではありません。(a,bはデフォルトのdouble型になっています。)
a,bはdouble型なので、何回もの演算を行わない限りは15~16桁の表示でも上手く動いているように見えます。

そもそもコンピュータ内部では2進数で数値を扱っているため、2.4等の数値を普通に扱えばどうしても誤差が生じてしまいます。
丸め誤差といいますが。(2進数で、10.011001100110・・・という値になる。)

試しに
コード:
#prompt
Dim c As Single
c=2.4
Print c
としてみてください。

対処法としては、全て10倍した値で保持いておいて、出力する時に10で割るという方法等が挙げられます。


質問はプログラミング質問板の方でしましょう。

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
投稿記事Posted: 2008年5月06日(火) 17:59 
ありがとうございました。

質問のあて先は、以後気をつけます。
自分では、質問箱の方に出したつもりでおりました。

続きなものですからもうひとつだけ質問させて下さい。
(以降は、質問箱に致しますのでご容赦下さい。)

コンピュータでは、正確な数値計算は、たとえ簡単な計算であっても
できないということでしょうか?


> それはcだけがsingle型になっているためです。バグではありません。(a,bはデフォルトのdouble型になっています。)
> a,bはdouble型なので、何回もの演算を行わない限りは15~16桁の表示でも上手く動いているように見えます。
>
> そもそもコンピュータ内部では2進数で数値を扱っているため、2.4等の数値を普通に扱えばどうしても誤差が生じてしまいます。
> 丸め誤差といいますが。(2進数で、10.011001100110・・・という値になる。)
>
> 試しに
コード:
#prompt
> Dim c As Single
> c=2.4
> Print c
としてみてください。
>
> 対処法としては、全て10倍した値で保持いておいて、出力する時に10で割るという方法等が挙げられます。
>
>
> 質問はプログラミング質問板の方でしましょう。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2008年5月06日(火) 19:27 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
お住まい: 埼玉県東松山市
>コンピュータでは、正確な数値計算は、たとえ簡単な計算であっても
>できないということでしょうか?

正確に計算できるものも多くあります。

扱う数値が、必ず10進数表記の時に有限桁になる数で、最大桁数と値の範囲が分かっている場合は
10進数での固定小数点演算/浮動小数点演算で正確に計算できます。

扱う数値が0又は正の整数の場合は、約43億までの数ならDWord型で保持できます。
QWord型を用いればもう少し大きな数まで正確に扱えます。

扱う数値が整数の場合は、約-21.5億~約21.5億までの数ならLong型で保持できます。
Int64型を用いればもう少し大きな範囲の数まで正確に扱えます。

ただし、円周率や√2を始めとする無理数を含む場合や複素数・四元数などを扱う場合は、
特殊な(数の特性を利用した固有の)方法を用いる場合を除いて正確に演算する事は困難です。

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年5月07日(水) 01:08 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 899
お住まい: 東京都
話に出てきた2.4は,コンピュータで普通にSingleやDoubleを使うと正確に表現できませんでしたが,それはコンピュータ特有のことではなく,日常で人間が使う十進法でも有限桁で計算するなら同じことが起こります。
例えば,十進法でも小数点以下1桁で打ち切って計算することにすれば, 1 ÷ 3 × 3は0.3 × 3 = 0.9となってしまう(1にならない!)という具合です。
十進法では無限小数にならない値も,二進法では無限小数になる場合がある(2.4もそう)なので,Single/Doubleの計算は一見不正確な結果に思われてしまうだけです。
#コンピュータが無限小数を扱えないからこういうことになるんだと言えば,やっぱりある意味コンピュータ特有の事柄かもしれません。

そういう意味で,「全て10倍した値で保持いておいて,出力する時に10で割る」などの十進法ベースの小数点数演算は,決して正確な計算ができるようになるわけではありません。単に,打ち切り誤差の発生が普通の人間の直感と一致するようになるだけです(まあこれは魅力的なことですが)。

Single/Double(だけに限りませんが)の値を出力するときは,適当な桁数で丸めて表示するといいのですが,BASICではPrint Usingくらいしかなくて不便なのが残念です。


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 5 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[10人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean