丸め誤差2

解決


はづき  2004-07-31 04:29:36  No: 115241  IP: [192.*.*.*]

魔界の仮面弁士 さんありがとうございます

一応調べてみたり、無理やり計算させてみたりするも
今度は別のどつぼにはまりました・・・

もちろん通貨型を使用し対策を!というのは考えていました
ぶち当たった現象は・・・
X = FIX(A / B * C)
という値の丸めについて
この時のXは整数値のみ取得したいのでFIXを使用しています

ABCXを全て通貨型に宣言しなおして
以下の式に書き換え
X = FIX(CCur(A / B * C))と直してよっしゃ!などとぬか喜びしていたら
あるところで
X = FIX(CCur(A * C / B))という式が出てきました

なぜこの二つの式の演算結果が異なってくるのでしょう?
また、通貨型は小数4桁ですよね?
ということは
10.99995なんて数字は11になってしまうのでしょうか?
それだと結局本末転倒・・・

丸めがある以上正確に表現できないor.Netに切り替えてDicimalでも使え!
という話もあるでしょうが
現状VB6なのでここまで行くとどうしようもないのでしょうか?

長くなりましたが、やりたいことは
割り算と掛け算、小数も出てくる演算がしたい!
整数部のみ取得したい!(その際小数は切り捨て)
vbは6で開発!
これ以上はどうしようもない!というところは本当にどうしようもないと思いますので仕様!
薄々お気づきかと思われますが、お金の関わっている仕事です・・・
1円ずれると・・・(泣)なんです・・・
よろしくお願いします・・・

編集    削除
特攻隊長まるるう  2004-07-31 05:41:23  No: 115242  IP: [192.*.*.*]

なんかもう何が聞きたいのか分からないんですが…
>X = FIX(CCur(A / B * C))と直してよっしゃ!などとぬか喜びしていたら
>あるところで
>X = FIX(CCur(A * C / B))という式が出てきました
>なぜこの二つの式の演算結果が異なってくるのでしょう?
…これって10進で言えば
10 / 3 * 3 と 10 * 3 / 3
の違いみたいなものじゃないですか?右から順にやれば割り算の余りを
吸収できなくなります。掛け算先にすればいいんじゃないですか?(^^;)

対象となる数値の桁数や使う数式、実際にその数式で出る不具合。
それをどうしたいのか?をもう少し具体的に書いて頂かないと…雲を
つかむような話なんですが?小数桁も大事…みたいな話をしてて結局
使うのは整数部のみとか言われても(汗)…経理の仕事とか無縁なので
理解できません。要は誤差の範囲が有効桁数に及ばない処理ならいい
のでは?と推測してるんですが…
丸めの無い(人間が手作業でやる?)正解となる計算式はあるんですか?
それを説明していただければ…もう少し何とか…なるかも?

編集    削除
魔界の仮面弁士  2004-07-31 06:56:16  No: 115243  IP: [192.*.*.*]

> X = FIX(CCur(A / B * C))と直してよっしゃ!などとぬか喜びしていたら
それだと意味がありませんよ。
「算術演算子」について、ヘルプで調べてみてください。


「/ 演算子」は、2 つの数値の商を計算し、結果を『浮動小数点数で』
返しますので、単に Currency型 / Currency型だと、やはり誤差が出ます。
(ただし、10 進型を渡したときは、浮動小数点にはなりませんけれどね)


> また、通貨型は小数4桁ですよね?
そうです。4桁固定です。


> 割り算と掛け算、小数も出てくる演算がしたい!
で。その精度はどこまで必要なのでしょうか?
まさか、
  A = 10 / 3
  B = A * 3
の時に、B が 10 になって欲しい、という事でしょうか?


桁数を無限に保持する事はできませんから、精度を上げたいのであれば、
データを「分数」にて計算するようなクラスを自作されては如何でしょう。

データを小数として保持するのではなく、分子と分母に分けて
整数として管理するようにしておけば、四則演算時にも、
「整数同士の掛け算」として扱えますから、誤差を最小限にできますよね。

# 手続きが複雑になる分、処理速度は多少犠牲になりますが、
# 分数計算のロジック自体は、「算数」の知識さえあれば組めるでしょうし。


そこまでの精度は必要ない、という事であれば、どこまでの精度を
求めているのか、具体的な仕様部分を教えてください。

編集    削除
ぴろあき  2004-08-03 01:14:50  No: 115244  IP: [192.*.*.*]

>or.Netに切り替えてDicimalでも使え!

VB6でもVariant型の内部処理形式としてDecimalは使えますよね。

ただし、Decimalだって循環小数を29〜30桁目を四捨五入するわけですから、
丸めることにはかわりないですが。。。

編集    削除
葉月  2004-08-04 18:14:26  No: 115245  IP: [192.*.*.*]

ご返答ありがとうございます

自分でも客観的に見て文章が意味不明であることに
今びっくりしています・・・

分数ロジックですか
今回別のメンバーが何とか解決策を見出した様子?なので
それを試してみます

分数ロジックに関してはひとつの知識として面白そうなので
個人的に組んでみます
クラスもあまり使ったことないのでその練習も兼ねて

コンピュータの不正確さを痛感したド素人葉月でした・・・
本当にご意見ありがとうございました

編集    削除
葉月  2004-08-04 19:29:54  No: 115246  IP: [192.*.*.*]

言い訳がましいですが、こいつ何も調べてねぇな!と思われるのもいやなので
一応VBのヘルプの方は質問以前に調べておいたことを補足しておきます
(一応MSDNやwebで極力調べてから質問するようには心がけています)

それにマイクロソフトのページで
CCUR(X / Y) * Y
という式を見て/演算子にCCURをつけるといいのかな?と推測の結果の式でした
大人の都合で「そんな時間はない!」という意見が返ってきたので
一応全て通貨型に型変換
全ての式を掛けてから割るへの共通化をまず施してみます

しょうがないので、うん千回に一回の誤差なら勘弁の方向で行っていきます

編集    削除