C++ 检查双变量是否包含整数而不是浮点

C++ 检查双变量是否包含整数而不是浮点,c++,c,floating-point,C++,C,Floating Point,我的意思是: double d1 =555; double d2=55.343 我想知道d1是一个整数,而d2不是。在c/c++中有没有一种简单的方法可以做到这一点?一个示例代码: if ( ABS( ((int) d1) - (d1)) )< 0.000000001) cout <<"Integer" << endl; else cout <<"Flaot" << endl; if(ABS(((int)d1)-(d

我的意思是:

  double d1 =555;
  double d2=55.343

我想知道d1是一个整数,而d2不是。在c/c++中有没有一种简单的方法可以做到这一点?

一个示例代码:

if (  ABS( ((int) d1) - (d1)) )< 0.000000001) 

 cout <<"Integer" << endl;

else

 cout <<"Flaot" << endl;
if(ABS(((int)d1)-(d1))<0.00000000 1)
cout怎么样

if (abs(d1 - (round(d1))) < 0.000000001) {
   printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
if(abs(d1-(圆形(d1)))<0.00000000 1){
printf“Integer\n”;/*不能使用“==”,因为我们担心精度*/
}
修正了工作时使用舍入来反映Anna发现的错误

替代解决方案:

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 */
}
if((d1-楼层(d1)<0.00000000 1)| |(d1-楼层(d1)>0.9999999)){
/*最好将下限值存储在温度变量中以加快*/
printf“Integer\n”;/*不能使用“==”,因为我们担心精度*/
}
还有另外一个方法是在地板上减去0.5,再加上abs(),与0.49999999相比,但我认为这不会是一个重大的性能改进

int iHaveNoFraction(double d){
    return d == trunc(d);
}
现在,如果没有大约40年的语言修改,它就不会是C了


< > >代码> > = > /代码>返回<代码> int >代码>,但在C++中,返回<代码>布尔O/COD>。至少在我的Linux发行版(Ubuntu)上,您需要声明
double trunc(double)
或者您可以使用
-std=c99
编译,或者声明level宏,所有这些都是为了让
声明它。

假设您有cmath
库,您可以根据它的属性检查数字。如果数字可能是负数,请确保您得到第一个

使用:

不要转换为
int
!你知道,数字
1.0e+300
也是一个整数

编辑:正如Pete Kirkham指出的那样,标准不能保证将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;
}
bool-isInteger(双d,双三角)
{
双absd=abs(d);
如果(absd-地板(absd)>0.5)
返回(ceil(absd)-absd)
#包括
#包括
int main()
{
双x,y,n;
x=某个值;
y=modf(x,&n);//将浮点值拆分为小数部分和整数部分
if(abs(y)
这个怎么样

if ((d1 - (int)d1) == 0)
    // integer

阿瓦卡几乎是正确使用modf,但细节是错的

modf返回小数部分,因此测试应该是modf的结果为0.0

modf接受两个参数,第二个参数应该是与第一个参数类型相同的指针。传递NULL或0会导致g++运行时出现分段错误。该标准没有规定通过0是安全的;它可能碰巧在avakar的机器上工作,但不要这样做

您还可以使用
fmod(a,b)
计算
a
b
通过1.0。这也应该给出分数部分

#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

}
#包括
#包括
int main()
{
双d1=555;
双d2=55.343;
双积分第1部分;
双积分第2部分;
使用名称空间std;

cout下面是测试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;
     }
};
#包括
使用名称空间std;
int main()
{
无效支票类型(双x);
双d1=555;
双d2=55.343;
支票类型(d1);
支票类型(d2);
系统(“暂停”);
返回0;
}
无效支票类型(双x)
{
如果(x!=(int)x)
{

cout假设c99和IEEE-754兼容环境

(trunc(x) == x)
是另一种解决方案,它(在大多数平台上)的性能略优于
modf
,因为它只需要生成整数部分。这两种方法都是完全可以接受的

请注意,
trunc
产生双精度结果,因此您不必像使用
(int)x
那样担心超出范围的类型转换



编辑:正如@pavon在评论中指出的,您可能需要添加另一个检查,这取决于您是否关心无穷大,以及如果
x
为无穷大,您希望得到什么结果。

在许多计算中,您知道浮点结果会有一个小的数值错误,这可能是由m数引起的乘法运算

所以你可能真正想找到的问题是这个数字在一个整数值的1e-5范围内。在这种情况下,我认为这样效果更好:

bool isInteger( double value )
{
    double flr = floor( value + 1e-5 );
    double diff = value - flr;
    return diff < 1e-5;
}
bool-isInteger(双值)
{
双flr=楼层(值+1e-5);
双差=值-flr;
返回差<1e-5;
}

我也面临着类似的问题。 因为我无论如何都需要绕双圈,所以我发现这是有效的:

double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()
double d=2.000000001;
int i=标准::圆形(d);
标准::晶圆厂(d-i)<10*标准::数值极限::ε()
#定义_ε0.000001
布尔闭合到整数(双d)
{
双整数,
分数=modf(d和整数);
if(分数<ε)
{
d=整数;
返回true;
}
if((1.0-分数)<\uε)
{
d=整数+1;
返回true;
}
返回false;
}

这将查看整数值的两侧,如果d在整数值的限制范围内,则设置d的值。

如果#为1.0000000001(可以返回,例如DB后端),则它将不起作用。整数(至少达到一定大小)在我能想到的浮点数的任何实际实现中都能精确表示,因此我认为对于这个特定问题,不必担心精度。如果d1=0.999999999999,情况会怎样?唯一的问题是底数对负数来说是错误的。您应该使用trunc()@雅各布:你不想使用最小值。你需要一个能代表你的精度的值
(trunc(x) == x)
bool isInteger( double value )
{
    double flr = floor( value + 1e-5 );
    double diff = value - flr;
    return diff < 1e-5;
}
double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()
#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;
}