-4

簡単な例を次に示します。

Dim si As Single
For si = 2.6 To 3.3 Step 0.1
  MsgBox si
Next si

私が取得する数値は次のとおりです (MsgBox に表示されるので、以下に示します)。

2.6
2.7
2.8
2.9
3
3.099999
3.199999
3.299999

そこで、データ型を Single から Double に変更して、何が起こるかを確認しようと考えました。今回は、.099999 型番号はありませんが、最後の項目 (反復) はスキップされ、欠落しており、存在しません。MsgBox ディスプレイに表示される結果は次のとおりです)。

2.6
2.7
2.8
2.9
3
3.1
3.2

最後の反復が欠落している場合、それは.299999のように追跡し、.3に到達することはないので、スキップしますか? ただし、これに関する問題は、これが発生した場合、これが発生するために前の反復の 1 つが 2 回表示されることです。これは、単一データ型の例で行われたように、最初の 10 進数では、3.0 が 2 回表示されていることに気付くでしょう。最初に「3」、次に「3.0」(「3.0」部分の後の数字 9 の 5 回の出現を無視/切り捨てた場合 - 「3.099999」)。

興味深いことに、Single データ型を使用して何かをループする別の関数は、上記の Double データ型の例とまったく同じ問題を表示し、上記の Single データ型の例にはまったく問題がありません。したがって、私がここにいる本当の理由は、Single Data Type ループが見つからず、「ステップ 0.1」(0.1 ずつインクリメントされる) を使用するときに最後の項目をスキップすることです。

「Step 0.1」と非整数データ型を使用してこれを行う信頼できる方法はありますか? そうでない場合、これらのカオスが発生するルールを知っていますか (つまり、カオスは予測可能ですか)? はぁ

皆さんもこれは面白いと思うだろうと思っていたので、理解できることを楽しみにしています。「for」と「step」を入力するとすぐに、ステップ演算子の使用方法に関するサンプルが表示され続け、何も役に立たなかったので、Googleで検索しても役に立ちませんでした。

これをどのように扱うか、またはこれを安全に行うか、そして/またはそもそもなぜそれが起こっているのかを知りたい. この特定の関数に整数を使用してループすることは避けたいと思います (そして、別の変数を使用して分割して 10 進型を取得します)。しかし、これはあなたたち、私のプログラマーの大君主に任せます。

私の例は VB6 で発生していましたが、これと同じ混乱が VB.NET や C# でも発生しているのだろうか? vbaとvbscriptで発生していると思います。これに関する情報も興味深いものであり、高く評価されます。

前もって感謝します。

モデレーターへ (質問を読む必要はありません): これは重複した投稿ではありません。他の人が他の言語 (C# など) で浮動小数点の問題を投稿している可能性がありますが、この (VB6) の質問に対する解決策は必ずしもC# の質問の解決策と同じです。同じ解決策がいくつかあるかもしれませんが、異なる解決策もあり、C# の投稿から別の解決策/回答を得ることはできません。結局のところ、私が興味を持っていたソリューションは、参照された C# の投稿では見つからなかった VB6 固有のソリューションでした。投稿を閉じようとする前にモッズに勤勉であることを強く勧めます。多くの投稿が不当に閉じられたのを見てきました場合によっては、一日の終わりに、価値を追加するのではなく、この Web サイトの Q & A スタイルから実質的な価値を取り除く段階に到達します。結論として、同様の見た目の投稿によって新しい情報/回答または解決策が得られる可能性さえある場合は、閉鎖を控えた方がよいでしょう. 特に質問が別の言語に関するものである場合、概念が類似または同じであっても、言語固有のさまざまなソリューションとソリューションが必ず存在します。

4

3 に答える 3

8

問題は、メモリ内での浮動小数点数の表現方法に帰着します。浮動小数点数がどのように表現されるかを理解するための良い参考文献へのリンクを他の多くの人が投稿しています。

ToStringシングルの代わりにダブルを使用しようとすると、数値は次のように増加します-値の完全な精度を出力しないため、デバッガーを使用して値を取得する必要がありました。

2.6
2.7
2.8000000000000003
2.9000000000000004
3.0000000000000004
3.1000000000000005
3.2000000000000006
3.3000000000000007

ご覧のとおり、最終値は for ループの最後よりわずかに大きいため、スキップされました。

代わりに整数を使用することで、for ループでの浮動小数点の問題を回避できますが、出力する値を取得するには、反復ごとに数値を 10 で割る必要があります。

Dim i As Integer
For i = 26 To 33 Step 1
        MsgBox(i / 10)
Next
于 2012-07-06T21:50:56.380 に答える
3

精度の代わりに小数を使用してみてください。

For i As Decimal = 2.6 To 3.3 Step 0.1
  MessageBox.Show(i.ToString)
Next

VB6 を使用している場合は、Currency タイプを使用してみることができます (JeffSiver が指摘したように)。

Dim i As Currency
For i = 2.6 To 3.3 Step 0.1
  MsgBox i
Next
于 2012-07-06T21:24:42.520 に答える
2

10を掛けて、ループに整数を使用します。使ってもdecimal同じような問題になると思います

于 2012-07-06T21:29:03.850 に答える