- - PR -
VB6とVB2005での計算結果の違い
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-06-02 18:53
業務アプリとかなら
金額に関するデータに浮動小数点を使うのは、 御法度なんだけどなぁ普通。 | ||||||||||||
|
投稿日時: 2008-06-02 21:04
じゃんぬねっとさん、rainさん、unibonさん、よねKENさん、未記入さん
お返事ありがとうございます。 できるだけ、誤差のでるまま新しいシステムを納品するのもいかがなものか。 と思っているので、旧システムとの誤差を認めてもらうか(チェックにならなくなるのでこれは難しいかもしれません)できれば旧システムの変更を勧めていけるように再度働きかけてみたいと思います。 ただ旧システムは新システム稼動と共に廃止されるシステムですので変更を認めてもらえるかも分かりませんが…。 みなさん、色々とありがとうございました。 | ||||||||||||
|
投稿日時: 2008-06-02 22:01
既に一段落しているようですが、少々気になりましたので
FPUのコントロールレジスタを覗いてみた所VB6では内部計算精度64bitになっている のに対しVC++や.NET実行環境(C#,VB.NET)では53bitで設定されているようです. 浮動小数点演算は内部ライブラリの実装によっても結果が変わってくるので一概に これだけが原因とは断言できませんが、ご参考まで. なおお書きになられている内容から演算過程で無限小数が発生している為、そのまま 実装した場合decimalもまた有限桁しか扱えない為誤差を無くす事は不可能かと. 通例このような計算では計算仮定をクライアントに提示・確認して浮動小数点などが 発生する部分は有効数字何桁とするといった取り決めを行っておく方が宜しいです. .NETモジュールではFPUのコントロールレジスタを操作する機能が公開されていない 事から、このレジスタをいじって無理矢理VB6の結果に一致させようとするのはフレームワーク の想定外として避けた方が良いかと思います. また使用している常駐ソフトなどプロセス内で起動する第三者のモジュールがランタイム 初期化等や実装者の無知により稀に浮動小数点の演算モードを変えてしまう場合などがある為、 同一プログラムであっても環境により浮動小数点演算の結果が完全一致しない可能性がある事 も留意しておいた方が宜しいかと思います. | ||||||||||||
|
投稿日時: 2008-06-02 22:12
今回の件で、とくに問題の原因となっているのは、要求定義にVB6の実装を必要としていることでしょう。
「数値は浮動小数点で持つので、開発環境や動作環境によって結果は不定になる」と定めることができれば良いのでしょうけど、それはさすがに無理ですよね。 | ||||||||||||
|
投稿日時: 2008-06-02 23:15
計算結果が同じになると思っている方がどうかしています。
VB2005はVB6に似た文法で.netアプリを作れる言語で、 そもそも互換性などはまったくありません。 これがマイクロソフトの思惑に反して VB6ユーザーの移行がなかなか進まなかった原因です。 最近のマイクロソフトはVB6ユーザーを 「新しいものを覚えようとしないアホ」 とこきおろしてますが、VB6でしかできないことがある以上 アホはお前の方だと言ってやりたいですね。 ちなみに私はC言語以外ではdoubleは使いません。 | ||||||||||||
|
投稿日時: 2008-06-02 23:27
もし問題があるとすれば検収方法に浮動小数点演算の完全一致を前提としている所でしょう.
FPU設定からも分かる通りVB6と.NET環境で開発環境の想定内では完全に値を一致させるのは 不可能ですし浮動小数演算のセオリーからしても有り得ない話です. ので計算結果がある範囲内で一致するというのを検収条件とするよう先方と交渉するべき かと思います. なお浮動小数点数の比較は両者の差の絶対値がある範囲内の誤差に収まるかでチェックするの が通例です. 比較誤差の桁数を絶対尺度とするか比較される数との相対尺度で比較するかは 演算の性格などによって変わってくるので、浮動小数点表現と数値計算の専門書などを参考に して下さい. なお整数化する場合にFixを使っているのは根本的に間違いなので自重される方が宜しいかと 思います. 数値が必ず整数になる事が確定しているならRoundを(これもまた整数以外では0.5 近傍での揺らぎがあります) またそうでない場合は上のような比較で判定し、最終段階まで 確定しないで演算を継続する方が良いです. 計算が単純で四則演算のみなら分数表記であれば誤差は発生しません、但し円周率や自然対数 の底、高階関数などの結果はやはり無限小数を含むものの近似値になりますので誤差を含みます. また分数表現は単純な計算以外では複雑な計算になると直ぐに分子と分母が非常に大きな桁になって しまう傾向が強く、多倍長で実装が必要になり、また約分過程ではRSAなどの根拠になっている 多倍長整数の因数分解や、高階関数近似の誤差も無くす場合には結局、数式処理を実装しなけ ればならなくなる為、演算の特性が分かっている限定的な小問題以外ではお勧めしません. 初期の想定ミスは否めないとは思いますが、このようにコンピュータ上での非整数系の演算は 常に誤差を伴うものという事を相手に説明して納得してもらう方が良いかと思います. | ||||||||||||
|
投稿日時: 2008-06-03 00:09
遅い時間までお返事ありがとうございます!
これからの解決方法はまだ確定していませんが、 とても勉強になりました。 なおかつとても説明しずらい事案でもある事に気付きました。 開発者およびそれにある程度携わる人であればある程度までいけると思うのですが、 その先が…(涙) テスト時の検収想定のミスや旧システムの型使用方法のミス…それらを挙げればきりがないですが、つい落としどころを…と思いこのような質問をしました。 まだまだ勉強不足な所が自覚できてよかったです。 | ||||||||||||
|
投稿日時: 2008-06-03 02:27
お客様はそんな知識はありませんのでしょうがないですね。
どこでどうこきおろしているのか興味があります。 URL を提示して頂けますか?
C では OK で他の言語ではダメとする、その深遠な考えを教えてください。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 |