给定:
double d;
int lsb;
以下编译:
lsb = (floor(d));
lsb = lsb % 10;
但是,以下内容不会:
lsb = (floor(d)) % 10;
IDE 强调了floor
的开头并报告:
表达式必须具有整型或无作用域枚举类型。
你可以组合这两行,但这需要一个强制转换:
lsb = static_cast<int>(floor(d)) % 10;
原因是存在多个重载std::floor
;注意以下几点:
double floor( double arg );
因此,floor(d)
是一个double
,不能直接(没有强制转换int
)与模运算符一起使用。
(floor(d))
返回一个double
,您可以通过将其存储在lsb
中来强制转换为int
这个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
,你首先得到一个表示d
的底值的double
,然后你自动将其转换为int
。如果要将其组合成一个表达式,则需要明确说明这一点:
double d;
int lsb = ((int)floor(d)) % 10;
或
int lsb = (static_cast<int>(floor(d))) % 10;