如果double变量包含整数而不是浮点,则检查它

时间:2009-10-05 18:19:23

标签: c++ c floating-point

我的意思如下:

  double d1 =555;
  double d2=55.343

我希望能够告诉d1是整数而d2不是。有没有一种简单的方法在c / c ++中做到这一点?

14 个答案:

答案 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)

avakar几乎是正确的 - 使用modf,但细节已经关闭。

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

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

您还可以使用fmod(a,b)来计算传递1.0的ab。这也应该给出小数部分。

#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;

编辑:更改它以反映正确的代码。