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>
usingnamespace 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;
}
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
inlinebool is_int(double f)
{
return f == std::trunc(f);
}
#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";
elseif (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.
@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."
> 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.
#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";
elseif (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.