- PR -

[基礎]固定小数と浮動小数について

投稿者投稿内容
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2004-02-13 14:26
るぱんです。
コード:

Dim i As Double
Dim dblX As Double
'dblX = 0.00001
dblX = 0
'For i = 1 To 99999
For i = 1 To 100000
'dblX = dblX + dblX
dblX = dblX + 0.00001
Next i
Stop
'以下イミディエイト
'?dblX
'0.999999999998084


ぢゃん♪様のおっしゃった通りになりました。(^^
ありがとうございます。

>Microsoft(違)
すまん。僕が悪かった!許してくれぇぇぇぇぇぇぇぇぇ!!
しかし、コメントアウトしたコードだとオーバーフローするんだ?
えぇ?申し開きしてみろぉ!!!(謎)


[ メッセージ編集済み 編集者: るぱん 編集日時 2004-02-13 14:28 ]
りばぁ
大ベテラン
会議室デビュー日: 2003/11/26
投稿数: 130
お住まい・勤務地: 愛知県
投稿日時: 2004-02-13 14:39
引用:

はにまるさんの書き込み (2004-02-13 13:51) より:
結果として、りばぁさんの意見、理解出来ました。 
今回は互いの前提条件が異なっている事が問題でしたね...
ご苦労をおかけ致します。



こちらこそ申し訳ありませんでした

引用:

強いて言えば
「型に対して誤った知識を持ち、誤った使い方を注意する」事の方が、
「内部構成の知識」より重要と私は思います。
 無論、何故、注意しなければ行けないか?をより良く理解する為にも
 内部構造の話も重要です。

 特に今回は、私の用語定義があやふやだったので、
 混乱を招いていますが。。。 ^^;



VBの型は結構いい加減ですから、逆にきちんと知っておく必要があるかもしれませんね・・


るぱんさんへ、
コメントアウトしたところは、dblXを2倍にしていく感じですよね?
それを99999回ですかぁ・・8バイトで足りますかねぇ?頭の中で計算できないので
分かりませんがTT
あと、いらぬ突っ込みかと思いますが、なぜカウンタもDouble型なのですか??(笑)

Double型の場合、200回くらい足せばもう誤差出ちゃいましたけど、
Currency型で同じようなことすると、何回やっても誤差でないんですよね・・
値の持ち方を考えると、単純な足し算とかだと、誤差なしでいいのかもしれませんね。
どなたか誤差が出る例があれば教えていただきたいです・・・

[ メッセージ編集済み 編集者: りばぁ 編集日時 2004-02-13 14:42 ]
ぢゃん♪
大ベテラン
会議室デビュー日: 2003/06/12
投稿数: 208
お住まい・勤務地: 都内
投稿日時: 2004-02-13 14:42
引用:

しかし、コメントアウトしたコードだとオーバーフローするんだ?


まぁ、0.00001×(2^99999) → 約4.995×(10^30097) だし
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2004-02-13 14:48
引用:

るぱんさんの書き込み (2004-02-13 14:26) より:

しかし、コメントアウトしたコードだとオーバーフローするんだ?



コメントアウトしたコードだと
1.79769313486231570E+308
の精度を超えるからのようですね。

ちなみに、.NETだと例外が発生せず+∞となります。

#修正:引用しすぎを修正


[ メッセージ編集済み 編集者: NAL-6295 編集日時 2004-02-13 14:48 ]
TomScissors
ベテラン
会議室デビュー日: 2003/06/05
投稿数: 79
投稿日時: 2004-02-13 14:54
>unibonさん
>http://www.geocities.co.jp/SiliconValley/4334/unibon/asp/valueerror.html
誤字発見!
>誤差が累積することを不正でいます
少し吹いてしまいました。

>るぱんさん
以下のようにしたいという事ではっ!?
Dim i As Long
Dim dblTeisu As Double
Dim dblX As Double
dblTeisu = 0.00001
dblX = 0
For i = 1 To 100000
dblX = dblX + dblTeisu
Next i
・定数っぽいのを定義
・iはDoubleじゃない

#引用間違えたので修正。
#お二人とかぶってしまった…

[ メッセージ編集済み 編集者: Tomscissors 編集日時 2004-02-13 14:56 ]
ぢゃん♪
大ベテラン
会議室デビュー日: 2003/06/12
投稿数: 208
お住まい・勤務地: 都内
投稿日時: 2004-02-13 14:58
引用:

りばぁさんの書き込み (2004-02-13 14:39) より:

Double型の場合、200回くらい足せばもう誤差出ちゃいましたけど、
Currency型で同じようなことすると、何回やっても誤差でないんですよね・・
値の持ち方を考えると、単純な足し算とかだと、誤差なしでいいのかもしれませんね。
どなたか誤差が出る例があれば教えていただきたいです・・・


C#のdouble, decimalでですが、ちょちょいと作ってみました。
コード:

double d = 0.0d, dd = 1.0d / 3.0d, dp = dd * 10000d;
decimal m = 0.0m, md = 1.0m / 3.0m, mp = md * 10000m;
for (int i = 0; i < 10000; i++)
{
d += dd;
m += md;
}
Console.WriteLine("{0}", d.ToString("0.0000000000000000000000000000000"));
Console.WriteLine("{0}", m.ToString("0.0000000000000000000000000000000"));
Console.WriteLine("{0}", dp.ToString("0.0000000000000000000000000000000"));
Console.WriteLine("{0}", mp.ToString("0.0000000000000000000000000000000"));
Console.ReadLine();


を実行すると
コード:

3333.3333333337300000000000000000000
3333.3333333333333333333330720000000
3333.3333333333300000000000000000000
3333.3333333333333333333333330000000


です。
decimalといえど、誤差が累積してしまえば、若干ながら誤差が拡大してしまうようです。

[ メッセージ編集済み 編集者: ぢゃん♪ 編集日時 2004-02-13 15:05 ]
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2004-02-13 15:07
引用:

TomScissorsさんの書き込み (2004-02-13 14:54) より:
>るぱんさん
以下のようにしたいという事ではっ!?
Dim i As Long
Dim dblTeisu As Double
Dim dblX As Double
dblTeisu = 0.00001
dblX = 0
For i = 1 To 100000
dblX = dblX + dblTeisu
Next i


仰るとおりです。

あ、そうか、単純にさっきのだと倍倍になっていくのか。
ごめんなさい。早とちりです。(汗

Doubleにしたのは途中であふれたからで、僕の意図的な正解はLongです。

もっとソース読み直さないとな。。。(滝汗

[ メッセージ編集済み 編集者: るぱん 編集日時 2004-02-13 15:13 ]
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2004-02-13 15:55
ほむらです。
--------
るぱん氏
僕も同じようなコード書いてました_| ̄|○illi

修正して確認しました。
Perlでも0.999999999999906になりますね。
後一回足す(=10001回)と1.00009999999991 になります。

#間違いに気が付いて削除

[ メッセージ編集済み 編集者: ほむら 編集日時 2004-02-13 16:08 ]

スキルアップ/キャリアアップ(JOB@IT)