2016-04-27 9 views
19

ではない床のすべてのダブルスをint型にキャストん: はなぜCのコードを考えるとC

#include <math.h> 
#include <stdio.h> 
int main(){ 
int i; 
double f=log(2.0)/log(pow(2.0,1.0/2.0)); 
printf("double=%f\n",f); 
printf("int=%d\n",(int) f); 
} 

私は出力を得る:

double=2.000000 
int=1 

fは明らかに、少なくとも2.0です。キャスト値が2でないのはなぜですか?

+11

でそれの前提のように思えます答えは偽です。実際の "問題"は、printfが浮動小数点数を丸めることです。 – user35702

+0

また、intがdoubleと同じサイズで、 'log((double)int_64_variable)'のようなことをする場合も考えられます。私は、このためにCプログラムを書くより紙でこれをやる傾向が強くなっています。 ;) – sjsam

+1

'int'へのキャストは床ではなくゼロに向かって切り捨てることにも注意してください。これは負の値に関係します。 – jamesdlin

答えて

34

二重の値が2未満

double=1.99999999999999978 
int=1 

だったので、それを試してみたが、この時間は

#include <math.h> 
#include <stdio.h> 
int main(){ 
int i; 
double f=log(2.0)/log(pow(2.0,1.0/2.0)); 
printf("double=%0.17f\n",f); 
printf("int=%d\n",(int) f); 
} 

は地獄のようにあなたがそれを経験する最初の時間を混乱いくつかの精度を追加します。今、あなたがこれを試してみたら

#include <math.h> 
#include <stdio.h> 
int main(){ 
int i; 
double f=log(2.0)/log(pow(2.0,1.0/2.0)); 
printf("double=%0.17f\n",f); 
printf("int=%d\n",(int) f); 
printf("int=%d\n", (int)round(f)); 
} 

値を正しく丸めるでしょう。あなたは(少なくともMac上)のmanページを見ると、あなたが以下のコメントを参照してくださいよ...

round, lround, llround -- round to integral value, regardless of rounding direction 

が、彼らは方向とはどういう意味ですか、それはすべてのIEEE 754に指定されています。あなたがチェックした場合different ways to round to an integer...フロアは1 :)に向けて

7

整数切り上げた値をとらないたこのケースではあるが、切り捨てを行い-ve infinityに向けて丸めとして言及されています。したがって、fが1.999999999999 [..] 9に等しい場合、int値は1になります。

また、より正確な可能性を望むように、文字数を考慮して切り上げ値を取る彼は2.000000であることを示すことができます。

7

浮動小数点型では、一部の数値を正確に表すことができません。数学的にも、calculation should be exactly 2は、IEEE754浮動小数点数を使用すると、結果は2よりわずかに小さいことが判明しました。詳細はthis questionを参照してください。 の代わりに%.20fの代わりに%.20fを指定して出力の精度を上げると、数値が正確に2ではなく、精度があまり高くない場合は結果が単純に丸められることがわかります。

しかしながら、浮動小数点型の完全な精度が使用されるintに変換し、それはちょうど2下に来るので、整数への変換結果が1

関連する問題