Check double variable if it contains an integer, and not floating point

C++CFloating Point

C++ Problem Overview


What I mean is the following:

  double d1 =555;
  double d2=55.343

I want to be able to tell that d1 is an integer while d2 is not. Is there an easy way to do it in c/c++?

C++ Solutions


Solution 1 - C++

Use std::modf:

double intpart;
modf(value, &intpart) == 0.0

Don't convert to int! The number 1.0e+300 is an integer too you know.

Edit: As Pete Kirkham points out, passing 0 as the second argument is not guaranteed by the standard to work, requiring the use of a dummy variable and, unfortunately, making the code a lot less elegant.

Solution 2 - C++

Assuming a c99 and IEEE-754 compliant environment,

(trunc(x) == x)

is another solution, and will (on most platforms) have slightly better performance than modf because it needs only to produce the integer part. Both are completely acceptable.

Note that trunc produces a double-precision result, so you don't need to worry about out of range type conversions as you would with (int)x.


Edit: as @pavon points out in a comment, you may need to add another check, depending on whether or not you care about infinity, and what result you want to get if x is infinite.

Solution 3 - C++

Assuming you have the cmath <math.h> library, you can check the number against it's floor. If the number might be negative, make sure you get the absolute first.

bool double_is_int(double trouble) {
   double absolute = abs( trouble );
   return absolute == floor(absolute);
}

Solution 4 - C++

avakar was almost right - use modf, but the detail was off.

modf returns the fractional part, so the test should be that the result of modf is 0.0.

modf takes two arguments, the second of which should be a pointer of the same type as the first argument. Passing NULL or 0 causes a segmentation fault in the g++ runtime. The standard does not specify that passing 0 is safe; it might be that it happens to work on avakar's machine but don't do it.

You could also use fmod(a,b) which calculates the a modulo b passing 1.0. This also should give the fractional part.

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

Solution 5 - C++

int iHaveNoFraction(double d){
    return d == trunc(d);
}

Now, it wouldn't be C if it didn't have about 40 years of language revisions...

In C, == returns int but in C++ it returns bool. At least on my Linux distro (Ubuntu) you need to either declare double trunc(double); or you could compile with -std=c99, or declare the level macro, all in order to get <math.h> to declare it.

Solution 6 - C++

How about

if (abs(d1 - (round(d1))) < 0.000000001) {
   printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}

Fixed up to work using rounding to reflect bug Anna found

Alternate solutions:

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 also another one with taking floor, subtracting 0.5 and taking abs() of that and comparing to 0.499999999 but I figure it won't be a major performance improvement.

Solution 7 - C++

How about this?

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

Solution 8 - C++

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

This looks at both side of the integer value and sets the value of d if it is within the limits of an integer value.

Solution 9 - C++

try:

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

Solution 10 - C++

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

Solution 11 - C++

In many calculations you know that your floating point results will have a small numerical error that can result from a number of multiplications.

So what you may really want to find is the question is this number within say 1e-5 of an integer value. In that case I think this works better:

bool isInteger( double value )
{
    double flr = floor( value + 1e-5 );
    double diff = value - flr;
    return diff < 1e-5;
}

Solution 12 - C++

I faced a similar questions. As I needed to round the double anyway, that's what I find working:

double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()

Solution 13 - C++

Just compare ceil and floor value of d

return floor(d)==ceil(d);

So, for d1=555, the above statement will return 555==555, i.e, true, so it's an integer.

And for d2=555.6, the above statement will return 555==556, i.e, false, so it's a double.

Solution 14 - C++

modf uses std::nearbyint(num) that why you should use nearbyint which return a double without decimal and may be faster.

#include <iostream>
#include <cmath>

int main() {
    double      number = 55.12;

    if (!(number - std::nearbyint(number))) {
      std::cout << "Is integer!";
    } else {
      std::cout << "Has decimal!";
    }
    
    return 0;
}

Solution 15 - C++

A sample code snipped that does it:

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

 cout <<"Integer" << endl;

else

 cout <<"Flaot" << endl;

EDIT: Changed it to reflect correct code.

Solution 16 - C++

Below you have the code for testing d1 and d2 keeping it very simple. The only thing you have to test is whether the variable value is equal to the same value converted to an int type. If this is not the case then it is not an integer.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvehomzzzView Question on Stackoverflow
Solution 1 - C++avakarView Answer on Stackoverflow
Solution 2 - C++Stephen CanonView Answer on Stackoverflow
Solution 3 - C++TJ LView Answer on Stackoverflow
Solution 4 - C++Pete KirkhamView Answer on Stackoverflow
Solution 5 - C++DigitalRossView Answer on Stackoverflow
Solution 6 - C++DVKView Answer on Stackoverflow
Solution 7 - C++AshwinView Answer on Stackoverflow
Solution 8 - C++user15942888View Answer on Stackoverflow
Solution 9 - C++Patrice BernassolaView Answer on Stackoverflow
Solution 10 - C++Kirill V. LyadvinskyView Answer on Stackoverflow
Solution 11 - C++Jeroen DirksView Answer on Stackoverflow
Solution 12 - C++DenisView Answer on Stackoverflow
Solution 13 - C++Mayur AgarwalView Answer on Stackoverflow
Solution 14 - C++Sky VoyagerView Answer on Stackoverflow
Solution 15 - C++VNarasimhaMView Answer on Stackoverflow
Solution 16 - C++KJPView Answer on Stackoverflow