我的意思如下:
double d1 =555;
double d2=55.343
我希望能够告诉d1是整数而d2不是。有没有一种简单的方法在c / c ++中做到这一点?
答案 0 :(得分:69)
使用std::modf
:
double intpart;
modf(value, &intpart) == 0.0
请勿转换为int
!您知道的数字1.0e+300
也是一个整数。
编辑:正如Pete Kirkham所指出的那样,传递0作为第二个参数并不能保证标准的工作,需要使用虚拟变量,不幸的是,使代码不那么优雅。
答案 1 :(得分:9)
假设您有cmath <math.h>
库,可以根据它floor检查数字。如果数字可能为负数,请确保先获得absolute。
bool double_is_int(double trouble) {
double absolute = abs( trouble );
return absolute == floor(absolute);
}
答案 2 :(得分:5)
假设符合c99和IEEE-754环境,
(trunc(x) == x)
是另一种解决方案,并且(在大多数平台上)将具有比modf
略好的性能,因为它只需要生成整数部分。两者都完全可以接受。
请注意,trunc
会产生双精度结果,因此您无需像(int)x
一样担心超出范围的类型转换。
编辑: @pavon 在评论中指出,您可能需要添加另一项检查,具体取决于您是否关心无穷大,以及您希望获得的结果{{1是无限的。
答案 3 :(得分:4)
modf返回小数部分,因此测试应该是modf的结果为0.0。
modf有两个参数,第二个参数应该是与第一个参数相同类型的指针。传递NULL或0会导致g ++运行时出现分段错误。标准没有规定传递0是安全的;可能是它恰好在avakar的机器上运行但是没有这样做。
您还可以使用fmod(a,b)
来计算传递1.0的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
}
答案 4 :(得分:3)
怎么样
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 */
}
Theres还有另外一个获得下限,减去0.5并取abs()并与之比较0.499999999,但我认为这不会是一个重大的性能提升。
答案 5 :(得分:3)
int iHaveNoFraction(double d){
return d == trunc(d);
}
现在,如果没有大约40年的语言修订,那就不会是C ......
在C中,==
返回int
但在C ++中它返回bool
。至少在我的Linux发行版(Ubuntu)上,您需要声明double trunc(double);
或者您可以使用-std=c99
进行编译,或者声明级别宏,以便让<math.h>
声明它。
答案 6 :(得分:2)
这个怎么样?
if ((d1 - (int)d1) == 0)
// integer
答案 7 :(得分:1)
#define _EPSILON_ 0.000001
bool close_to_int(double &d)
{
double integer,
fraction = modf(d, &integer);
if(fraction < _EPSILON_)
{
d = integer;
return true;
}
if((1.0 - fraction) < _EPSILON_)
{
d = integer + 1;
return true;
}
return false;
}
这会查看整数值的两侧,如果 d 在整数值的范围内,则设置它的值。
答案 8 :(得分:0)
尝试:
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;
}
答案 9 :(得分:0)
#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
}
}
答案 10 :(得分:0)
下面是测试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;
}
};
答案 11 :(得分:0)
在许多计算中,您知道您的浮点结果会产生一个很小的数值误差,这可能会导致多次乘法。
所以你真正想要找到的是问题是这个数字在整数值的1e-5之内。在这种情况下,我认为这更好:
bool isInteger( double value )
{
double flr = floor( value + 1e-5 );
double diff = value - flr;
return diff < 1e-5;
}
答案 12 :(得分:0)
我遇到了类似的问题。 因为我需要绕过双人,这就是我发现的工作:
double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()
答案 13 :(得分:-1)
执行此操作的示例代码段:
if ( ABS( ((int) d1) - (d1)) )< 0.000000001)
cout <<"Integer" << endl;
else
cout <<"Flaot" << endl;
编辑:更改它以反映正确的代码。