C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 91 を表示中)
■54124 / )  Re[1]: VB6.0 Int関数を使用しての切り捨て処理について
□投稿者/ 魔界の仮面弁士 (1852回)-(2010/10/05(Tue) 19:59:14)
2010/10/05(Tue) 20:26:28 編集(投稿者)
# その表記だと VB.NET の話になってしまうかと。>やじゅさん
# まぁ、意味するところは同じですけれどね。


■No54121 (ペケ さん) に返信
> Int関数を疑いましたが、Int関数は少数以下を取り除いた整数を返す
少数→小数という突っ込みはさておき、正確には、
整数を返すのではなく整数部を返す関数ですね。

Int 関数は切り捨て(−∞方向への整数丸め)を行いますが、型変換は行いません。
Fix 関数は切り捨て(0方向への整数丸め)を行いますが、型変換は行いません。
整数型に変換する関数と誤解している人が多いので……一応念のため。


> Microsoft VisualBasic 6.0 SP5
SP6 ではなく?


> 実行してみると「0.0849」が返却されます。
詳細は後述しますが、Int する前の段階で既に誤差が含まれています。たとえば
 dblValue = (dblValue1 + dblValue2) / 2
の段階では、約 0.084999999999999992 近辺の値になっているようですね。


開発環境では、
 dblValue = 0.084999999999999992
と書いても、自動的に
 dblValue = 0.085
に丸められてしまい、その違いがデバッガでも視認しにくいですが、
 Debug.Print CDbl("0.084999999999999992") = CDbl("0.085")
は False となります。


> 何か解決策があれば教えていただければ幸いです。
Double を使うのはやめて、Currency に変更しましょう。
Currency では桁が足りない場合は、10 進型で代用します。
(10進型は、Variant 型の内部形式のひとつです)


'通貨型や10進型を利用する。
Dim Value1 As Currency
Dim Value2 As Currency
Dim Value  As Currency
Dim Result As Currency

Dim intDig As Integer
Dim valX   As Currency

'「^ 演算子」は Double 型の値を返すが、
'今回は演算結果が整数なので、格納誤差は発生しない。
intDig = 4
valX = CCur(10 ^ intDig)

'「@」は通貨型を意味する型宣言文字です。
Value1 = 0.06@
Value2 = 0.11@

'ちなみに 10進型の場合は型宣言文字が無いので、「CDec("0.06")」のようにして
'文字列型を10進型に変換することで対応します。

'なお、Double や Single の値を CDec や CCur することは避けてください。
'(型変換以前に、もともとの値に誤差が含めれている可能性があるため)


'「/ 演算子」は、通貨型に対する演算では Double 型を返しますが、
'内部2進数ゆえ、2 で割っても格納誤差は発生しません。
'(ちなみに「/ 演算子」を 10進型に対して使った場合は、結果も10進型です)
Value = (Value1 + Value2) / 2

'こうすれば、「0.085」という値を取り出すことができます。
Result = Int(Value * valX) / valX


>   dblValue1 = 0.06
>   dblValue2 = 0.11
Double 型で誤差なく処理しようとするのであれば、元となる値も、
2 進小数で誤差なく格納できる範囲でなければ意味がありません。

元データが「近似値」であれば、計算結果もブレてしまいますからね。
下記の資料が参考になるかと思います。
http://salvw.miscnotes.com/index.php/archives/53

返信 編集キー/


管理者用

- Child Tree -