Дано:
double d;
int lsb;
Следующие компиляции:
lsb = (floor(d));
lsb = lsb % 10;
Однако следующее не делает:
lsb = (floor(d)) % 10;
IDE подчеркивает начало floor
и отчеты:
Выражение должно иметь целочисленный или незаданный тип enum.
Вы можете объединить эти две строки, но для этого понадобится приведение:
lsb = static_cast<int>(floor(d)) % 10;
Причина в том, что существует множество перегрузок std::floor
; обратите внимание на следующее:
double floor( double arg );
Следовательно, floor(d)
это double
и не может быть использован напрямую (без приведения к int
) с оператором по модулю.
(floor(d))
возвращает double
который вы бросили в int
храня его в lsb
это int
хорошо для %
, Если вы не бросили его в int
, это не удастся.
В этом выражении высказывание
lsb = lsb % 10;
оба операнда оператора %
иметь целочисленный тип.
Пока в этом выражении высказывание
lsb = (floor(d)) % 10;
один операнд оператора %
имеет тип с плавающей точкой, а второй операнд имеет целочисленный тип.
Оператор %
определяется только для целочисленных типов или для перечислений с незаданной областью.
Из стандарта C ++ (2014) (5.6 Мультипликативные операторы)
2 Операнды * и / должны иметь арифметические или незаданные
тип перечисления; операнды% должны быть целыми или незаданными
тип перечисления. Обычные арифметические преобразования выполняются на
операнды и определяют тип результата.
Вы можете привести первый операнд к типу int
сделать выражение правильным.
оператор %
требуемый целочисленный тип (например, int
).
Когда ты пишешь lsb % 10
, lsb
имеет тип int
так что все работает отлично.
Тем не мение, floor(d)
возвращается double
так что когда пишешь (floor(d)) % 10
вы пытаетесь использовать оператор %
с типом с плавающей запятой, который является ошибкой.
Итак, чтобы использовать оператор %
вам нужно преобразовать это double
в int
, как это:
lsb = int(floor(d)) % 10;
floor
на самом деле это функция, которая возвращает тип с плавающей точкой в 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
Назначая floor(d)
в lsb
вы сначала получите double
которая представляет собой половую стоимость d
затем вы автоматически преобразуете его в int
, Вы должны четко указать это, если хотите объединить это в одно выражение:
double d;
int lsb = ((int)floor(d)) % 10;
или же
int lsb = (static_cast<int>(floor(d))) % 10;