C ++为什么不能将这两个操作合并为一行?

时间:2017-11-28 13:45:29

标签: c++ floor mod

假设:

double d;
int lsb;

以下编译:

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

但以下情况并非如此:

lsb = (floor(d)) % 10;

IDE强调floor的开头并报告:

  

表达式必须具有整数或未整合的枚举类型。

5 个答案:

答案 0 :(得分:11)

你可以将这两行合并,但这需要一个演员:

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

原因是std::floor存在多个重载;请注意以下事项:

double      floor( double arg );

因此,floor(d)double,无法使用模运算符直接使用(不使用强制转换为int)。

答案 1 :(得分:2)

(floor(d)) returns a double 您将其int存入lsb

int适用于%。如果你没有把它投入int,它就会失败。

答案 2 :(得分:2)

在此表达式声明中

lsb = lsb % 10;

运算符%的两个操作数都有整数类型。

在此表达式声明中

lsb = (floor(d)) % 10;

运算符%的一个操作数具有浮点类型,第二个操作数具有整数类型。

运算符%仅针对整数类型或未范围的枚举进行定义。

来自C ++(2014)标准(5.6乘法运算符)

  

2 *和/的操作数应具有算术或无范围   枚举类型; %的操作数应具有整数或未整数   枚举类型。通常的算术转换是在   操作数并确定结果的类型。

您可以将第一个操作数强制转换为类型int以使表达式正确。

答案 3 :(得分:1)

运算符%需要整数类型(如int)。

当您撰写lsb % 10时,lsb的类型为int,因此一切正常。

但是,floor(d)会返回double,因此当您编写(floor(d)) % 10时,您尝试使用带有浮点类型的运算符%,这是一个错误。

因此,为了使用运算符%,您需要将double转换为int,如下所示:

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

答案 4 :(得分:0)

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;