check if a value is integer or float

closed account (STD8C542)
I've to check if a value is integer or not. I've tried p == int(p), floor(p) == ceil(p) and then i manually did the floor value as p-fmod(p,1). Even though p and i are same, the if condition is returning false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <bits/stdc++.h>
using namespace std;

int main() {
	double avg, p, i = 1;
	    string s = "12.2222"; //taking input as string
	    avg = stod(s); //converting to double
	    cout << avg << endl;
	    p = (double)5000*avg; //5000 is the least number which gives integer value
	    i = (p-fmod(p,1)); //manually implementing floor
            cout << p << endl << i << endl;
	    if(p == i){
	            cout << i << endl;
	   }
	   else cout << 1 << endl;
}
Last edited on
Just because p and i look the same when printed by cout doesn't mean they are equal. cout defaults to printing only 6 significant digits, so if the values differ beyond that point you won't see it. Try this as the first line of main:

 
    cout.precision(20);

As for testing if a double is an integer you might try (I haven't):

1
2
3
4
inline bool is_int(double f)
{
     return f == std::trunc(f);
}

Last edited on
The Standard Library can do that for you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <type_traits>

template <typename T>
void what_am_i( T x )
{
  if      (std::is_integral       <decltype( x )> ::value) std::cout << x << " is an integer\n"; 
  else if (std::is_floating_point <T>             ::value) std::cout << x << " is a double\n";
  else                                                     std::cout << x << " is not a number\n";
}

int main()
{
  auto z = -7;
  auto f = 6.28318'53071;
  auto s = "five";
  
  what_am_i( z );
  what_am_i( f );
  what_am_i( s );
} 

Notice that the traits objects take a type. You can obtain a type with either the decltype operator or via a type name, both exemplified above.

Hope this helps.

[edit]
Oh, this too: https://en.cppreference.com/w/cpp/header/type_traits
Last edited on
@iotaa, are you trying to determine the TYPE (which Duthomhas has for you), are is your problem that you have a float (or double) and need to know if the value it contains represents an integer value (which your code sample SEEMS to indicate).

Or, as I hold my head sideways, or you in need of determining if a string (presumably from some input source, keyboard, file, whatever) is or is not an integer?

All VERY different things, and I'm not sure I can really tell which just yet.

That last one, just looking in a string, might be interpreted as "an integer has either no decimal (in US, comma in Europe perhaps), or it has no non-zero digits past the decimal."





Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <string>
using namespace std;

bool isWholeNumber( const string &s, int &n )
{
   n = 0;
   if ( s.size() == 0 || s[0] == ' ' ) return false;

   size_t pos;
   try
   {   
      n = stoi( s, &pos );              // Try to convert
   }
   catch( ... )
   {
      return false;                     // Not convertible
   }

   if ( pos < s.size() ) return false;  // Additional chars (including blanks) after

   return true;
}


int main()
{
   string tests[] = { "", "22.222", "whoops!", "1234", "1e5" };
   int n;
   for ( string s : tests )
   {
      if ( isWholeNumber( s, n ) ) cout << s << " is the int " << n << '\n';
      else                         cout << s << " is not an int\n";
   }
}


 is not an int
22.222 is not an int
whoops! is not an int
1234 is the int 1234
1e5 is not an int



Depends a bit whether you want 10.0 to be an integer or a float (in C++ terms, it's not an int).
Last edited on
> i = (p-fmod(p,1)); //manually implementing floor
modf might give you better answers.

NAME
modf, modff, modfl - extract signed integral and fractional values from floating-point number

SYNOPSIS
#include <math.h>

double modf(double x, double *iptr);
float modff(float x, float *iptr);
long double modfl(long double x, long double *iptr);


That is, if you're trying to determine that a floating point value has the form of xxxx.0
Ie, the fractional part is zero, and you can store the integral part in an integer with no loss of information.

Hmm, yes. I don’t remember the OP having that particular example...

String to int/double/whatever

If you are just looking to identify a string as an integer/double/whatever, the best way to do that is try to convert it to an integer/double/whatever. If it converts, then it is. If the conversion fails, it is not.

This question is asked so often that my stock function for this kind of thing is memorized down to the character: string_to<type>(). Notice the bonus check to avoid treating things like "42 grapes" (or "3.14") as an integer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <optional>
#include <sstream>
#include <string>

template <typename T>
std::optional <T> string_to( const std::string& s )
{
  std::istringstream ss{ s };
  T result;
  ss >> result >> std::ws;
  if (!ss.eof()) return {};
  return result;
}

template <typename T>
void what_am_i( T x )
{
  if      (string_to <int>    ( x )) std::cout << x << " is an integer\n";
  else if (string_to <double> ( x )) std::cout << x << " is a double\n";
  else                               std::cout << x << " is not a number\n";
}

int main()
{
  auto z = "-7";
  auto f = "6.2831853071";
  auto s = "five";
  
  what_am_i( z );
  what_am_i( f );
  what_am_i( s );
}

Does double hold an integer value?

This gets a little more complicated, because Floating-Point Arithmetic Is Not Your Friend — it is all too easy to create values with non-integer parts. Using fmod() is the right idea, but you should also be checking that the difference is greater than some epsilon.
Last edited on
Topic archived. No new replies allowed.