プロが教える店舗&オフィスのセキュリティ対策術

ドルでおつりを計算するプログラムをC++で書きましたが、時々1セント少なくなって
しまいます。おつり計算の時は正しいのですが、結果(double) を intにアサインする時にそうなってしまいます。どうすれば正しく動くようになるのかわかりましたら、教えてください。よろしくお願いします。コンパイラーはマックのg++を使用しています。

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
//declare variables
doubleamountOwes = 0.0;
doubleamountPaid = 1.0;
doubleamountOfChange = 0.0;
intnumberOfDollars = 0;

intcents = 0;

cout << fixed << setprecision(2);

for (amountOwes = 0.0; amountOwes < 1.00; amountOwes = amountOwes + 0.01) {

amountOfChange = amountPaid - amountOwes;

if (amountOfChange >=0 ) {
numberOfDollars = (int) amountOfChange;
cents = (int) (100.0 * (amountOfChange - (double) numberOfDollars));
cout << "Paid $"<<amountPaid<< " Owes $"<<amountOwes<< " ";
cout << "change "<<100 * (amountOfChange - numberOfDollars)<< " cents ";
cout << "cents= " << cents << " cents\n";
}
}
//system ("pause");
return 0;
} //end of main function

A 回答 (7件)

この問題に限っていえば、


計算中のお金の単位をドルからセントにかえて整数計算し
最後に表示するときにドルとセントに換算すれば誤差は出なくなります。
    • good
    • 0

そういえば、Macでは使えたかどうか忘れましたが、GCCは_Decimal64とか_Decimal128といった10進浮動小数点型をサポートしていますね。


C++ではなく、Cでなければ使えなかったと思いますが...
    • good
    • 0

厳密に言えば「浮動小数点を使う」のがご法度ではなく「10進でない表し方を使う」のがご法度では>#4. 浮動小数であっても 10進で

あればさほど問題ないはず. TR 24733 が現在進行中ですね.
    • good
    • 0

C++ に限りませんが、金額などを扱う場合、浮動小数点を使うことはご法度です。

しかし、C++ では固定小数点はサポートされていませんので、工夫する必要が出てきます。

詳しい人なら自分で固定小数点クラスを作るのもいいですが、昔から使われているのは、long などで、内部的には 1000 倍(1000 の必要はありませんが)にして持たせる、などです。ただし、扱う金額を 1000 倍しても long の範囲で収まることが条件です。内部では 1000 倍した値で各種計算を行い、最終的に元の桁に戻します。延々と除算を繰り返すようなことをやると丸めが積み重なっていきますが、倍数を大きくすればするほど、その丸め誤差は小さくなってはいきます。
    • good
    • 0

因みに、2進数化すると



0.1=0.000110011001100110011001100110011001100110011001100110011001100110...

0.01=0.000000101000111101011100001010001111010111000010100011110101110000...

と言う循環少数になります。

循環部分を [] で表すと

0.1=0.0[0011]...

0.01=0.00[00001010001111010111]...

となります。

コンピュータのメモリは有限ですから、無限に続く循環少数を正確に表す事は出来ません。
    • good
    • 0

0.1、0.01は、double、float等に2進数化すると「循環少数」になる為、必ず誤差が出ます。



なので、0.1、0.01を扱う場合は、BCD(二進化十進数)を用いるか、固定小数点を用いねばなりません。

これは、C++に限った話ではありません。どんな言語でも同じです。

「セントを1として、すべて整数型で扱う」のも「固定小数点」と同義です。
    • good
    • 0

double型を使っていることがそもそもの間違いです。


汎整数型を使って、内部的にはすべてセントで表現するようにしましょう。
    • good
    • 0
この回答へのお礼

皆さん、
回答をありがとうございました。もともと最初から間違っていたのですね。汎整数型を使ってみます。

お礼日時:2011/09/15 20:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!