1

Given:

double d;
int lsb;

The following compiles:

lsb = (floor(d));
lsb = lsb % 10;

However the following does not:

lsb = (floor(d)) % 10;

IDE underlines the beginning of floor and reports:

expression must have integral or unscoped enum type.

YSC
  • 38,212
  • 9
  • 96
  • 149
Sentinel
  • 441
  • 1
  • 6
  • 25

5 Answers5

11

You can combine those two lines, but this would need a cast:

lsb = static_cast<int>(floor(d)) % 10;

The reason why is the existence of multiple overloads of std::floor; note the following:

double      floor( double arg );

Hence, floor(d) is a double and cannot be used directly (without a cast to int) with the modulo operator.

YSC
  • 38,212
  • 9
  • 96
  • 149
2

(floor(d)) returns a double which you cast into a int by storing it in lsb

This int is good for %. If you don't cast it into int, it will fail.

2

In this expression statement

lsb = lsb % 10;

the both operands of the operator % have an integer type.

While in this expression statement

lsb = (floor(d)) % 10;

one operand of the operator % has a float type and the second operand has an integer type.

The operator % is defined only for integer types or for unscoped enumerations.

From the C++ (2014) Standard (5.6 Multiplicative operators)

2 The operands of * and / shall have arithmetic or unscoped enumeration type; the operands of % shall have integral or unscoped enumeration type. The usual arithmetic conversions are performed on the operands and determine the type of the result.

You could cast the first operand to the type int to make the expression correct.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

operator % required integral type (like int).

When you write lsb % 10, lsb is of type int so everything works fine.

However, floor(d) returns double, so when you write (floor(d)) % 10 you're trying to use operator % with a floating point type which is an error.

So in order to use operator % you need to convert that double to int, like this:

lsb = int(floor(d)) % 10;
Maxim Yanchenko
  • 156
  • 1
  • 4
0

floor is actually a function that returns a floating-point type, in C++11:

     double floor (double x);
      float floor (float x);
long double floor (long double x);
     double floor (T x);           // additional overloads for integral types

By assigning floor(d) to lsb, you first get a double which represents the floored value of d, then you automatically cast it to int. You need to be explicit about this if you want to combine it into one expression:

double d;
int lsb = ((int)floor(d)) % 10;

or

int lsb = (static_cast<int>(floor(d))) % 10;
Aurel Bílý
  • 7,068
  • 1
  • 21
  • 34