質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

4410閲覧

VB6にて、小数(Double)から整数(Integer)への暗黙変換時の切捨/切上のルールについて

apple_159

総合スコア1

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2022/01/05 09:43

VB6にて、小数(Double)から整数(Integer)への暗黙変換時の切捨/切上のルールについて

VB6からVB.NETへのコンバートをした際に、
それぞれの言語で少数部が”5”のとき、小数(Double)から整数(Integer)への暗黙変換時の値が異なりました。
VB.NETは銀行丸め(偶数丸め)となることは理解できたのですが、VB6の仕様が不明です。
VB6の少数部が5であるときの、切捨/切上の仕様を教えていただけますでしょうか。

【例1】小数 → 整数(暗黙変換)
VB6:360.5→361 奇数に切上される
.NET:360.5→360 偶数に切捨てられる

【例2】小数 → 整数(暗黙変換)
VB6:367.5→368 偶数に切上される
.NET:367.5→368 偶数に切上される

補足

VB6はランダムに切捨/切上を行っているわけではなく、「360.5」であれば必ず「361」となり、
何かしらの法則を持っているように見えます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOZ6.0

2022/01/05 11:21 編集

Dim dblValue As Double Dim intValue As Integer dblValue = 360.5 intValue = dblValue Debug.Print intValue VB6 も 360 になりませんか? 銀行家の丸めになるはずですが・・・
apple_159

2022/01/06 00:10

投稿をありがとうございます。 すみません。状況が正確ではありませんでした。 Integer*Doubleの結果をInteger型に格納する際に発生しております。 【例】 350*1.03=360(Integer型)
KOZ6.0

2022/01/06 06:33 編集

回答のほうに転記しました。
KOZ6.0

2022/01/06 06:32 編集

回答のほうに転記しました。
apple_159

2022/01/06 06:22

わかりやす例をありがとうございます。 つまり、 VB6では演算を内部的には2進数で行っており、その際に2進数では「1.03」を表現しきれない(桁落ちしている?)ため、演算結果が変わっているという理解でよろしいでしょうか? もし認識に誤りがなければベストアンサーとさせていただきたいため、回答のほうに投稿をお願いいたします。
cx20

2022/01/06 16:08

蛇足ですが、VBScript だと、 WScript.Echo CInt(CInt(350) * CDbl(1.03)) は 361 でなく 360 でした。(VB6 と同じ結果になると思ったのですが・・)
guest

回答2

0

ベストアンサー

1.03 は2進数に変換できないので、内部的には 350 * 1.03 = 360.5 にはなりません。
たぶん、360.5 よりちょっと大きくなっていると思われます。

VB6

1Dim intValue1 As Integer 2Dim intValue2 As Integer 3Dim intValue3 As Integer 4intValue1 = 360.5 5intValue2 = 350 * 1.03 6intValue3 = CLng(350) * 103 / 100 7Debug.Print intValue1 8Debug.Print intValue2 9Debug.Print intValue3 10結果 11360 12361 13360

もういっちょ実験

VB6

1Dim dblValue As Double 2Dim i As Integer 3dblValue = 0 4For i = 1 To 100 5 dblValue = dblValue + 1.03 6Next 7Debug.Print dblValue 8Debug.Print dblValue = 103 9Debug.Print dblValue > 103 10Debug.Print dblValue < 103 11結果 12 103 13False 14True 15False

1.03 は内部的には 1.03 より大きい値となっているようですね。
Debug.Print dblValue で 103 と表示されるのが厄介です。

VB.NET の動きを VB6 に合わせるとなると悩ましいですね。
金額計算であれば、Double を使ってた前任者が悪い!ということで逃げちゃいますかね・・・

投稿2022/01/06 06:31

編集2022/01/06 08:18
KOZ6.0

総合スコア2707

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

浮動小数点の性なんでDoubleにせずCurrecyとかを使う方がいいと思います。

vbaでも以下のようになります。

vba

1?cint(350*ccur(1.03)) 2 360 3?cint(350*cdbl(1.03)) 4 361

投稿2022/01/06 04:26

sousuke

総合スコア3830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

apple_159

2022/01/06 06:24

回答をありがとうございます。 本来は暗黙変換は使用しないほうがいいと思っておりますが、今回はVB6からマイグレーション時に発見した事象となり、.NETでVB6と同じ挙動としたことが目的になります。
sousuke

2022/01/06 06:36

仕様の理解が質問の内容でしたね。ごめんなさい。 多分ですけど.netとvb6のdouble型は同じdouble型でもサイズが違うはずです。 なので浮動小数の誤差が出るタイミングが違うだけで 「vb6では正しくなるけど、.netでは正しくならない」部分や 「両方とも正しくならない」部分がいつかでるのではないかと予想します。 ?0.1*3=0.3 False 個人的には上記のような感じになるので仕様の理解というのはあまり 必要性を感じておらず、「やってはいけないこと」として理解しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問