- PR -

VB6とVB2005での計算結果の違い

投稿者投稿内容
ぴぃ子
常連さん
会議室デビュー日: 2008/02/21
投稿数: 34
投稿日時: 2008-06-02 13:07
いつもお世話になっております。
OSはWinXP(SP2)です。

元々VB6で開発されているアプリをVB2005(ASP.NET)で開発しました。
ところが、VB6とVB2005で同じロジックであるにもかかわらず、計算結果が違うという
問題が発生しました。
---問題のコード(千円単位の金額を求める)---
dbl金額=Fix((dbl単価 * dbl数量(Idx)) / 1000)

変数は全てdouble型を使用しています。
また、数量は先に過去実績などから割ったりしている為に無限小数点(という言い方でいいのでしょうか?)
例えば3.333333333333333....(10/3など割り切れない計算)の様な数値であることが多いです。
ここで金額=4,500、数量=23.333333333333....という値で計算すると
VB6では104 VB2005では105という計算結果になります。

ここで、VB2005はFix計算前にVB側で丸められているという判断をして
VB2005のロジックを以下の様に変更しました。
dbl金額 = Fix((dbl単価 * CDbl(dbl数量.ToString)) / 1000)

これで上記の例の分は解決したのですが、コード変更後
今度は金額=4,500、数量=33.333333333333....という値で計算すると
VB6=150 VB2005=149というようになり
誤差が発生するようになりました。この場合は変更前のロジックだと150で同じ結果が得られます。

VB6と同じ計算結果を得られるようにする為にはどのようにすればよいのでしょうか?

行き詰っているので、VB2005でVB6での計算結果を得られるようにしてみるか?とも
思ってしまいましたが、それでは常にVB6の実行環境が必要になるし…。

VB6の方を変更できれば一番早いと打診はしているのですが
既に運用中のシステムなので、VB2005の結果をVB6に合うように。という話になっています。
また、VB6のシステムを新規開発したVB2005のシステムのチェックに使用しているので
見逃してもらう事もできません。

わかりずらい説明ではありますが、みなさんの知恵を拝借させていただけるとありがたいです。
どうぞよろしくお願い致します。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-06-02 14:03
またお客さんから無理難題を言われているんですね
VB6の計算結果がおかしいと主張して、認めてもらうという手段が最善だと思いますが、
難しそうですね…何か説得力のある資料があればよいのですが。

引用:

ぴぃ子さんの書き込み (2008-06-02 13:07) より:

VB6と同じ計算結果を得られるようにする為にはどのようにすればよいのでしょうか?



http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=44107&forum=36&start=0
上に挙げたスレッドの最後で、もとはーどやさんが分析されていますが、VB6の挙動を再現させるのは非常に困難だと思います。
私には、「VB6を使って計算をする」以上の答えは思いつきません…。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2008-06-02 16:35
参考になる?
VB6のINT(FIX)関数の動作について(microsoft.com)
ぴぃ子
常連さん
会議室デビュー日: 2008/02/21
投稿数: 34
投稿日時: 2008-06-02 16:59
rainさん、かずくんさん 御返事ありがとうございます。

rainさん:
 >…何か説得力のある資料があればよいのですが。

そうですね。明確な動作の基準が資料としてあればいいのかもしれません(涙
推測で断言してもツッコミ入れられると終わってしまうので…。


かずくんさん:
 何故か、桁数を多く扱えるという点で小数点はdoubleで使用しているシステムが
多数を占めています。
確かに10進型を使うのがいいのかもしれませんが、VB6とVB2005で違う結果という説明には繋がらないのが悲しいところです。


どのような対応に落ち着くか分かりませんが、まだ模索してみます。
何か「これを!」という対応方法や説得力のある資料を御存知の方がいらっしゃいましたら御教授いただけるとありがたいです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2008-06-02 17:08
浮動少数を失くしてから計算する。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-06-02 17:30
[追記]
この発言は、技術的に嘘が含まれているので注意してください。後の未記入さんの発言を参照してください。
この発言は、話の持って行き方の参考程度に留めておいてください m(_ _)m
[/追記]

「VB6とVB2005で計算結果が違う」という点は、横においといたほうがいいと思います。
具体例でもって「事実として違いは存在する」ことを認めてもらうことはできても、その理由までは説明できないでしょう。
Microsoftに質問して、納得のいく回答が得られればよいのですが、なかなか難しいと思います。

「VB6のアプリでdouble型で計算しているのがそもそもの問題」という方向に論点を持って行って、「VB2005で作るアプリではdecimalで計算するので、誤差は発生しません! 旧システムとの計算結果に違いがあっても、それは旧システムのほうに誤差があるからです!」という方向に持って行くのがいいのかな、という気がします。
もっとも、既にVB2005のアプリができあがっていたら、これはこれで結構痛い修正ですが…

あるいは「VB6のアプリ側は修正できない」という前提を崩せればよいのですが。
例えば↓のような、直感的におかしいと思うような結果を見せて、
「VB6の結果は絶対だ」という固定観念にヒビを入れてみるとか…。
http://tukaenai-pg.cocolog-nifty.com/blog/2006/01/vb6_c6e2.html

# 書いているうちにまとまりがなくなってきましたorz

[ メッセージ編集済み 編集者: rain 編集日時 2008-06-03 09:53 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-06-02 17:35
VB6 で Fix((a * b) / c) だけを計算する Function を持った、ActiveX コントロールを作り、それを VB2005 から呼び出す。

以下、追記。

一応書いておきますが、お勧めするわけではありません。工数が限られていて、難しいことは考えずに手っ取り早く片付けたい、というような場合の非常手段です。

[ メッセージ編集済み 編集者: unibon 編集日時 2008-06-02 19:51 ]
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2008-06-02 17:46
rainさんと概ね同意見なのですが、

引用:

rainさんの書き込み (2008-06-02 17:30) より:

「VB6のアプリでdouble型で計算しているのがそもそもの問題」



ここで考えが詰まってしまいました。
VB6アプリも自社から提供しているアプリだったら、なかなか苦しいなと。

それでもやはりVB2005ではDecimalを使って実装できるように
政治的な対応で頑張る方が、お互いに幸せになれると思います。

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