私が意味することは次のとおりです:
double d1 =555;
double d2=55.343
D1は整数で、d2は整数でないことを伝えたいのですが。 c/c ++でそれを行う簡単な方法はありますか?
使用する - std::modf
:
double intpart;
modf(value, &intpart) == 0.0
int
に変換しないでください!番号 1.0e+300
も整数です。
編集:ピート・カーカムが指摘するように、2番目の引数として0を渡すことは、標準では機能しないことが保証されているため、ダミー変数を使用する必要があり、残念ながら、コードのエレガントさが大幅に低下しています。
C99およびIEEE-754準拠の環境を想定し、
(trunc(x) == x)
もう1つの解決策であり、整数部分を生成するだけでよいため、(ほとんどのプラットフォームで)modf
よりもわずかに優れたパフォーマンスが得られます。どちらも完全に許容されます。
trunc
は倍精度の結果を生成するため、(int)x
のように範囲外の型変換を心配する必要はありません。
編集:@ pavonがコメントで指摘しているように、無限大に関心があるかどうか、およびx
無限です。
avakarはほぼ正しく、modfを使用しましたが、詳細はオフになりました。
modfは小数部を返すため、modfの結果が0.0であることをテストする必要があります。
modfは2つの引数を取り、2番目の引数は最初の引数と同じ型のポインターでなければなりません。 NULLまたは0を渡すと、g ++ランタイムでセグメンテーション違反が発生します。この規格では、0を渡すことが安全であるとは規定されていません。それはたまたまavakarのマシンで動作するかもしれませんが、それをしないでください。
a
modulo b
を1.0として計算するfmod(a,b)
を使用することもできます。これも小数部分を与える必要があります。
#include<cmath>
#include<iostream>
int main ()
{
double d1 = 555;
double d2 = 55.343;
double int_part1;
double int_part2;
using namespace std;
cout << boolalpha;
cout << d1 << " " << modf ( d1, &int_part1 ) << endl;
cout << d1 << " " << ( modf ( d1, &int_part1 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d1 << " " << fmod ( d1, 1.0 ) << endl;
cout << d1 << " " << ( fmod ( d1, 1.0 ) == 0 ) << endl;
cout << d2 << " " << fmod ( d2, 1.0 ) << endl;
cout << d2 << " " << ( fmod ( d2, 1.0 ) == 0 ) << endl;
cout.flush();
modf ( d1, 0 ); // segfault
}
いかがですか
if (abs(d1 - (round(d1))) < 0.000000001) {
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
アンナが発見したバグを反映するために丸めを使用するように修正
代替ソリューション:
if ((d1 - floor(d1) < 0.000000001) || (d1 - floor(d1) > 0.9999999999)) {
/* Better store floor value in a temp variable to speed up */
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
床を取り、0.5を引いてabs()を取り、0.499999999と比較する別の方法もありますが、パフォーマンスが大幅に向上することはないと思います。
_int iHaveNoFraction(double d){
return d == trunc(d);
}
_
さて、約40年の言語修正がなければ、Cにはなりません...
Cでは、_==
_はint
を返しますが、C++ではbool
を返します。少なくとも私のLinuxディストリビューション(Ubuntu)では、double trunc(double);
を宣言するか、_-std=c99
_を使用してコンパイルするか、レベルマクロを宣言して、_<math.h>
_を宣言する必要があります。それ。
これはどう?
if ((d1 - (int)d1) == 0)
// integer
試してください:
bool isInteger(double d, double delta)
{
double absd = abs(d);
if( absd - floor(absd) > 0.5 )
return (ceil(absd) - absd) < delta;
return (d - floor(absd)) < delta;
}
多くの計算で、浮動小数点の結果には、いくつかの乗算から生じる可能性のある小さな数値誤差があることがわかっています。
ですから、あなたが本当に見つけたいのは、整数値の1e-5の範囲内にあるこの数です。その場合、私はこれがうまくいくと思います:
bool isInteger( double value )
{
double flr = floor( value + 1e-5 );
double diff = value - flr;
return diff < 1e-5;
}
#include <math.h>
#include <limits>
int main()
{
double x, y, n;
x = SOME_VAL;
y = modf( x, &n ); // splits a floating-point value into fractional and integer parts
if ( abs(y) < std::numeric_limits<double>::epsilon() )
{
// no floating part
}
}
私は同様の質問に直面しました。とにかくダブルを丸める必要があったので、それが私が機能しているものです:
double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()
以下に、d1とd2をテストして非常にシンプルに保つためのコードを示します。テストする必要があるのは、変数の値がint型に変換された同じ値と等しいかどうかだけです。そうでない場合は、整数ではありません。
#include<iostream>
using namespace std;
int main()
{
void checkType(double x);
double d1 = 555;
double d2 = 55.343;
checkType(d1);
checkType(d2);
system("Pause");
return 0;
}
void checkType(double x)
{
if(x != (int)x)
{
cout<< x << " is not an integer "<< endl;
}
else
{
cout << x << " is an integer " << endl;
}
};