0

I want to read a double number and determine if the input is Integer or double. The problem is that when I enter 1.00 (which is double) I get the result as integer

double a;
cin >> a;
if (a == int(a))
    cout << "Integer";
else
    cout << "Double";
JustSomeGuy
  • 3,677
  • 1
  • 23
  • 31
Florian
  • 29
  • 8
  • 4
    Read as a string, and then see if the string contains a decimal separator (could be `','` as well, depending on locale settings). For conversion and further validation use e.g. [`std::stod`](https://en.cppreference.com/w/cpp/string/basic_string/stof). – Some programmer dude Mar 25 '19 at 14:20
  • The result is not an integer, your check is simply wrong. you declare `a` to be a double, so `cin >> a;` will assign whatever you type to a double, so `a` will never be an Integer. If you want to check whether the input is formatted like an integer or a floating point type (float, double, long double) and contains e.g. a `.` like `1.0` or `.5`, assign the input to a string and check how the value is formatted. – Elijan9 Mar 25 '19 at 14:23
  • I already know this method, but what I am asked to do is to read from a double not a string. – Florian Mar 25 '19 at 14:24
  • 2
    If you read as a double then you really can't tell if the user entered 1.0 or 1. The double doesn't store or retain a difference. – drescherjm Mar 25 '19 at 14:25
  • #Elijan9 I have made several tests and all of them show me that 1.0 is integer rather than double – Florian Mar 25 '19 at 14:27
  • drescherjm even when I read from integer (int a) and try 1.0 I still get the result as integer – Florian Mar 25 '19 at 14:31
  • 4
    A variable of type *double* is never an integer. Presumably that's what a call a double whose fraction is 0. Use this: http://www.cplusplus.com/reference/cmath/modf/ – Hans Passant Mar 25 '19 at 14:32

3 Answers3

3

You can read into a string and check if it contains the decimal separator. Assuming it is '.', here's an example implementation:

#include <iostream>
#include <string>

int main()
{
  std::string s;
  std::cin >> s;
  std::cout << ((s.find('.') == std::string::npos) ? "integer" : "double") << std::endl;
  return 0;
}

You also have to check for exponents (like 2e-1). Here's one way to do it all:

#include <iostream>
#include <string>

int main()
{
  std::string s;
  std::cin >> s;
  if (s.find_first_of(".,eE") == std::string::npos)
    std::cout << "integer" << std::endl;
  else
    std::cout << "double" << std::endl;
  return 0;
}
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • My task is to read from a double and thats why I am stuck for several hours – Florian Mar 25 '19 at 14:35
  • 4
    @Florian You're stuck because your task is impossible. You cannot read a double and then know what text was used to produce that double. That information was lost when the conversion to a double was performed. The **only** way to do this, as the answer above states, its to read the input as **text**, and analyse the text. Then convert the text to a double if that's what you wish to do. – john Mar 25 '19 at 14:38
  • You would also need to check if the input contains an exponent. For instance 123e-2 is a double, but doesn't contain a decimal separator. – john Mar 25 '19 at 14:49
  • No problem hoenstly the task is very simple just could not understand why 1.00 is not double because when we want to convert int to double we can simplly say (2 + 2 = 4 integer) (2 + 2.00 = 4 double) – Florian Mar 25 '19 at 14:58
  • @john thanks for pointing out. Tried to add that in but I used `strpbrk` because I couldn't find a direct C++ replacement. Is there any? – Aykhan Hagverdili Mar 25 '19 at 15:10
  • 1
    @Florian 1.00 *is* a double. What makes you think it isn't one? – Aykhan Hagverdili Mar 25 '19 at 15:13
  • Ayxan sure it is double but when I put( int a ) in my code instaed of (double a) and intered (1.00 ) I was still getting same resut 1.00 / 1 integer and this is the reason why I have asked – Florian Mar 25 '19 at 15:16
  • @john and ayxan thank you so much for your great effort – Florian Mar 25 '19 at 15:17
  • 1
    @Florian it's a bit like `int a = 1.00;` and `double d = 1;` compiler casts those to fit into the variable you created. And whenever you try to compare an `int` and a `double`, the integer is cast to a double first, and then they are compared. Meaning `1 == 1.00` and `1.00 == 1.00` are precisely the same thing – Aykhan Hagverdili Mar 25 '19 at 15:21
  • Ok, I have got it – Florian Mar 25 '19 at 15:25
2

In your if statement you are casting a to an int. This is just going to truncate the decimal value.

1==1 is always true as is 1.0 == 1

I would suggest looking at this answer: How to validate numeric input C++

tswanson-cs
  • 106
  • 13
0

Perhaps std::variant is an elegant way to solve your problem. std::variant<int, double> can store both an int or a double. Dependent on what you store the internal type will change.

#include <variant>
#include <string>
#include <cassert>


bool isInt(const std::variant<int, double> &intOrDouble) {
    try {
      std::get<double>(intOrDouble); 
    }
    catch (const std::bad_variant_access&) {
        return false;
    }
    return true;
}

int main()
{
    std::variant<int, double> intOrDouble;
    intOrDouble = 12.0; // type will be double -> return will be 1
    //intOrDouble = 12; // type will be int    -> return will be 0

    return isInt(intOrDouble); 
}
schorsch312
  • 5,553
  • 5
  • 28
  • 57