2017-02-28 7 views
5

私のプログラムでは、ダブルが精度を失っているという奇妙な動作がありました。私のcoutは正しい値を示していたが、依然として行動は予想外だった。したがって、私はデバッグし、発見さえgdbが予期しない値を表示します。続き は簡略化されたシナリオである:gdbが間違ったdouble値を表示しています

double length =2.11; 
//gdb shows 2.10 here but prints 2.11 correctly using cout at the end 
cout<<"length; //It prints 2.11 correctly here 

は、多くの場合、そのような問題は、デバッグが可能な限り多くのプリントを使用しているオプションと唯一の選択肢ではありません生産シナリオに見つけるのは難しいです。 この問題を回避するにはどうすればよいですか?

+1

間違った質問(あなたが動機づけを忘れて、実際にはいくつかの[XY問題](http://xyproblem.info)...)があるためです。あなたがコメントしたように、* numbers *を操作するのではなく、いくつかのバロックな長さ表現( '2.11'は2フィートと11インチを意味するとコメントしたので) –

+1

' double'を使うと、http: //floating-point-gui.de/ –

+0

@BasileStarynkevitch:絶対に良いアドバイス。この知識に武装して、あなたはまた、パーティーでうんざりします。 – Bathsheba

答えて

6

と仮定すると、IEEE754倍精度浮動小数点、2.11に最も近いdouble

2.109999999999999875655021241982467472553253173828125

std::cout若干小さいが、デフォルトで適切に四捨五入してくれているが、GDBは、小数点以下2桁に切り捨てているように見えます。

+0

どうしたらいいですか?私は二重変数を 'double var = 2.11'とし、2がfeetsを表し、11がインチを表すと仮定すると、11から11の代わりに10を作るので、ここから0.11の部分をどのように抽出できますか? – anurag86

+3

これは'解決するのは簡単ではありません。なぜ 'struct'を' feet'と 'inches'を別々にモデリングするのですか? 1フィート13インチから2フィート1インチのようなものに変換する「正規化」メソッドを構築することもできます。 – Bathsheba

+2

このような表現をすることは大きな間違いです。 'double'は*近似* [実数](https://en.wikipedia.org/wiki/Real_number)です。あなたのデータは数字でもありません。それをある長さに変換する(そして、できれば)*変換*する。'std :: string'、' std :: pair ') –

2

実数はあ​​なたの場合と同じように振る舞いますが、それについてはあまり気にしません。あなたはそれを避けるように計画しておいて、二重価値以上の平等チェックを行うための空間を作りました。

1:[大学のプロジェクトでこれをしようとしました]、オーダー10^-4に数字を扱う整数倍の値を使用するには

ここであなたのための2つのもっともらしいハックです。例:1.2345を格納するには、整数12345のように格納し、10000とします。これで正しく印刷でき、これによっても等価チェックを行うことが可能になります。

2:double値の精度がすでにわかっている場合は、オフセットを使用できます。例:2.109999の精度が小数点以下2桁の場合は、 (int)((2.109999 + .005)* 100)のような値を使用します。それに応じて印刷します。

1:あなたは値の精度に制御することが

しかし、これらの両方のハックは、次のことを前提としています。 2:実際に正確な値を印刷する必要があります。

関連する問題