6

私は天井関数を試していて、いくつかの奇妙な結果を得ています。10進数に100を掛けてceil演算を実行すると、特定の結果が得られます。ただし、その乗算の結果に対して直接ceilを実行すると、まったく異なる出力が得られます。もう1つのひねりは、これらの異なる結果が特定の数に対してのみ発生することです。どんな助けでもいただければ幸いです。

#include <stdio.h>
#include <cmath>

int main ()
{
cout << "The ceiling of " << 411 << " is " << ceil(411) << endl;
cout << "The ceiling of 4.11*100  is " << ceil(4.11*100) << endl;

cout << "The ceiling of  " << 121 << " is " << ceil(121) << endl;
cout << "The ceiling of 1.21*100  is " << ceil(1.21*100) << endl;;
}


OUTPUT:

The ceiling of 411 is 411
The ceiling of 4.11*100  is 412
The ceiling of  121 is 121
The ceiling of 1.21*100  is 121
4

3 に答える 3

9

ここでの問題は、浮動小数点数をコンピューターで確実に表すことができないことです。つまり、4.11はとして表されません4.11が、それに非常に近いものとして表されます。そして、この「4.11に非常に近い数」にを掛けると100ceil製品のは412、非常に驚​​いたことになります。しかし、浮動小数点数がどのように格納および取得されるかを理解すれば、まったく驚くことではありません。


この興味深いデモンストレーションをご覧ください。

float a = 3.2; //3.2 is double!
if ( a == 3.2 )
    cout << "a is equal to 3.2"<<endl;
else
    cout << "a is not equal to 3.2"<<endl;

float b = 3.2f; //3.2f is a float. Note: f is appended to make it float!
if ( b == 3.2f )
    cout << "b is equal to 3.2f"<<endl;
else
    cout << "b is not equal to 3.2f"<<endl;

出力:

aは3.2に等しくない
bは3.2fに等しい

ここでideoneで実験してください:http ://www.ideone.com/pAGzM

変数のタイプをaからfloatに変更してみてください。結果をもう一度double確認してください。

于 2011-04-06T06:56:57.290 に答える
5

FAQから:

[29.16]浮動小数点がそれほど不正確なのはなぜですか?なぜこれは0.43を印刷しないのですか?

#include <iostream>

 int main()
 {
   float a = 1000.43;
   float b = 1000.0;
   std::cout << a - b << '\n';
   ...
 }

免責事項:丸め/切り捨て/近似によるフラストレーションは、実際にはC++の問題ではありません。それはコンピュータサイエンスの問題です。ただし、人々はcomp.lang.c ++でそれについて質問し続けるので、以下は名目上の答えです。

回答:浮動小数点は概算です。32ビット浮動小数点のIEEE標準は、1ビットの符号、8ビットの指数、および23ビットの仮数をサポートします。正規化された2進仮数は常に1.xxxxx...の形式であるため、先頭の1が削除され、24ビットの仮数が効果的に取得されます。数値1000.43(および、0.1のような実際に一般的な数値を含む、他の多くの数値)は、floatまたはdouble形式で正確に表すことはできません。1000.43は、実際には次のビットパターンとして表されます(「s」は符号ビットの位置を示し、「e」は指数ビットの位置を示し、「m」は仮数ビットの位置を示します)。

 seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
 01000100011110100001101110000101

シフトされた仮数は1111101000.01101110000101または1000+7045/16384です。小数部は0.429992675781です。24ビットの仮数を使用すると、浮動小数点の16Mの精度で約1つの部分しか得られません。double型は、より高い精度(53ビットの仮数)を提供します。

また、[29.17]を参照してください。浮動小数点比較が機能しないのはなぜですか?

于 2011-04-06T06:58:34.813 に答える
2

このceil(x)関数は、 未満ではない最小の整数を返しますx

4.11入力した (またはのような1.21) 定数は正確に表現されていないため、わずかに小さい数またはわずかに大きい数で表されたり、まれに等しい数で表されたりすることがあります。たとえば、コンパイラは定数4.11をわずかに大きい数として表すため、4.11*100たまたま 411 よりもわずかに大きくなりますceil(4.11*100) == 412(412 は 411 よりわずかに大きい数以上の最小の数であるため) が、1.21わずかに小さい数として表されるため1.21*100、121 よりもわずかに小さくなります。そうceil(1.21*100)==121

また、乗算も正確ではないことに注意してください。

于 2011-04-06T07:24:21.477 に答える