2

I'm a beginner and I am looking for a way to check if a quotient in C++ is an integer.

For example:

int a;
double b;
cin >> a;
b = a / 4;

How do I know that b is not an integer (something like 5/4=1.25)?

4 Answers4

5

In languages like C when declaring a variable of an integer type, the value therein always will be an integer. However I guess what you're asking is, how to check if the result of a computation is a integer value. If you're doing arithmetic with integer types the most naive to understand way to do this, is to perform the inverse operation and test if the result matches the original input.

EDIT If both operands are of integer type (as before the question edit), then you can do this:

b = a / 4;
if( b*4 == a ){
    cout << "a/4 is integer";
}

However there are other ways to do this. For example using the remainder operator % (often confused with modulo – or rather a misnormer). On many CPU architectures the operation performing a division also gives the remainder. This

b = a / 4;
if( b%4 == 0 ){
    cout << "a/4 is integer";
}

will be close to optimal, because a single CPU instruction will perform both computations (over the first two lines) and the comparision will usually test for a special flag set by the division operation if no remainder was left.

*However if floating point arithmetic enters the pictures (as how after the question edit), things become a little bit more troublesome. You no longer can do the inversion test, because floating point arithmetic is imprecise¹.

If all you're interested in is the remainder/modulo, your best bet is using the fmod function and then testing if the result is within the margin of precission error epsilon.

if( DBL_EPSILON > fmod(a, 4) ){
        cout << "a/4 is integer (within double floating point precision)";
}

If you're in need of both quotient and remainder then my preferred method is to truncate and subtract (which is usually faster):

double b = a/4.;
double b_r = b - trunc(b);
if( DBL_EPSILON > fabs(b_r) ){
        cout << "a/4 is integer (within double floating point precision)";
}

1: for the majority of numbers involved; there's a set of numbers, which when used in floating point arithmetic operations will yield exact results. But this is only a small subset of all the numbers representable by floating point.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Conflated in what way? – Lightness Races in Orbit Mar 11 '18 at 14:04
  • @LightnessRacesinOrbit: Stupid autocorrect. I meant to write "confuse", or rather misnormer. Fixed it. – datenwolf Mar 11 '18 at 14:06
  • 1
    @datenwolf • I think the word you are looking for is "misnomer". – Eljay Mar 11 '18 at 14:14
  • Right, but that means the same thing. "Conflated" as a word wasn't a problem, but I was asking where the conflation is. As far as I can see, modulo and remainder are two words for the same thing. When you apply `a%b` you are obtaining the value of `a` in a "modulo `b`" numeric system. Is this not consistent with mathematics? Is the problem something to do with negative operands maybe? – Lightness Races in Orbit Mar 11 '18 at 14:17
  • And yeah it's "a misnomer" or "misnamed", not "misnormed" ;) – Lightness Races in Orbit Mar 11 '18 at 14:21
  • @LightnessRacesinOrbit: No, modulo and remainder are mathematically not the same thing. It comes down to the definition of arithmetic rings. The result of a modulo operation (by definition) must be non-negative. However the C "modulo" operator produces negative numbers for negative input. This can be toublesome in applications that rely on numbers being element of an arithmetic ring. See https://www.lemoda.net/c/modulo-operator/ and https://math.stackexchange.com/questions/519845/modulo-of-a-negative-number – datenwolf Mar 11 '18 at 14:32
  • @datenwolf: In other words "yes it has to do with negative operands"? Okay thanks – Lightness Races in Orbit Mar 11 '18 at 14:36
3

You don't need to check whether b is an integer, because it always will be. You declared it int.

Furthermore, because both a and 4 are also integers, a/4 is integer division, so even the expression can never be fractional.

If you fix all of that, one way to see whether a floating-point value represents a whole number is to compare its original value with one deliberately truncated to an integer:

foobar == static_cast<int>(foobar)

However, as with any floating-point operations this is potentially susceptible to rounding errors so you would need to be quite a bit more specific with your general requirements.

In the particular case shown, it would be much simpler to check modulo instead: 5 % 4 is not zero, so 5/4 is not whole.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2

Before the edit:

Your a and b variables are of type int as you declared them as such. They will remain of type int no matter the values you try to supply to them via the standard input. The type and a result of the a / 4 expression is also an int because all operands are integers involved in integer division.

After the edit:

If b is declared to be of type double it will remain of type double but will receive the cut-out result of an integer division as a / 4 is of type int. So if all operands are integers the result of an arithmetic expression will also be an integer. To make it of type double cast one of the operands to double:

double b = static_cast<double>(a) / 4;

or

double b = a / 4.;
Ron
  • 14,674
  • 4
  • 34
  • 47
1

As other answers suggest, if you assign the division to a float you'll be getting an integer value always, since in C++ (and most languages) integer division results in an integer.

In fact, you don't even need b to be a float. You can do one of the following:

Use the modulo operator <- recommended

int a;
std::cin >> a;
if (a % 4 == 0) { /* do something */ }

Use a divisor-specific divisibility test

int a;
std::cin >> a;
if (a & 0x11 == 0) { /* do something */ }

An integer is divisible by 4 if its least-significant 2 bits are 0. But, in fact, the compiler will probably optimize the previous test to this one.

Multiply the integral quotient

If you intended to use a/4 anyway, try:

int a;
std::cin >> a;
auto b = a / 4; /* b is an int... */
if (b * 4 == a) { /* do something */ }

This isn't very useful for the case of a fixed divisor; but if it hadn't been fixed, you might do:

int a;
std::cin >> a;
std::cin >> c;
auto b = a / c;
if (b * c == a) { /* do something */ }
einpoklum
  • 118,144
  • 57
  • 340
  • 684