- PR -

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

投稿者投稿内容
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-06-03 09:49
今更ですが、私が書いた内容に「decimalでは誤差がない」など、大嘘な発言が含まれていることをお詫びします m(_ _)m

引用:

未記入さんの書き込み (2008-06-02 22:01) より:

なおお書きになられている内容から演算過程で無限小数が発生している為、そのまま
実装した場合decimalもまた有限桁しか扱えない為誤差を無くす事は不可能かと.



こちらに関して、参考になるBlogのエントリがありましたので貼っておきます。
http://blogs.wankuma.com/nakap/archive/2008/06/03/141021.aspx

引用:

未記入さんの書き込み (2008-06-02 23:27) より:



の未記入さんの発言に全面的に同意します。
1点だけ補足すると、偶数丸めではない、いわゆる四捨五入をおこなう場合はMath.Round(double, MidpointRounding.AwayFromZero) または Math.Round(decimal, MidpointRounding.AwayFromZero) を使ってください。(VB2005以降で使えます)
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2008-06-03 11:07
引用:

未記入さんの書き込み (2008-06-02 22:01) より:
既に一段落しているようですが、少々気になりましたので
FPUのコントロールレジスタを覗いてみた所VB6では内部計算精度64bitになっている
のに対しVC++や.NET実行環境(C#,VB.NET)では53bitで設定されているようです.


これで合点がいきました。
V6.0ではCPU内部で80bit浮動小数点で計算しているので、計算結果をDouble型変数に格納するときに64bit浮動小数点へと丸目がおこなわれるのですね。その過程で125に変換されるのでしょう。
VB.NETでは64bit浮動小数点数のまま演算されるので、変数に格納するときに丸めはおこなわれず、124.xxxxxxxxxと言う値になる。その後小数点以下を切り捨てると124になると。

dbl金額 = Fix((CSng )((dbl単価 * dbl数量.ToString) / 1000))
とすれば、たぶんVB6と同じ演算結果になるでしょう。

一番良いのはこの機会に仕様バグを直すことだとおもうな。
dbl金額 = (単価 * 分母 / 1000 * 分子)ってな感じ。

_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-06-03 11:15
多分に勘が含まれるのですが、

引用:

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

dbl金額=Fix((dbl単価 * dbl数量(Idx)) / 1000)



ここは、
コード:
dbl金額 = Math.Floor(Math.Round(dbl単価 * dbl数量(Idx), MidpointRounding.AwayFromZero) / 1000)


とするといい感じの結果になるのかなぁ、と思いました。
こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2008-06-03 12:20
引用:

甕星さんの書き込み (2008-06-03 11:07) より:

一番良いのはこの機会に仕様バグを直すことだとおもうな。
dbl金額 = (単価 * 分母 / 1000 * 分子)ってな感じ。



dbl金額 = (単価 * 分子) / (1000 * 分母)ってな感じ。じゃなくてですか?
#スレッド斜め読みなので見当違いだったらスルーして下さい。

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