129

怎么会出现在下面的代码片段中

int a = 7;
int b = 3;
double c = 0;
c = a / b;

c正如人们所期望的那样,最终的值为 2,而不是 2.3333。如果ab是双打,答案确实转向 2.333。但可以肯定的是,因为c 已经是双精度数,所以它应该与整数一起使用?

那怎么int/int=double行不通呢?

4

10 回答 10

186

这是因为您使用的是 的整数除法版本operator/,它需要 2int秒并返回一个int。为了使用double返回 a 的版本,必须将double至少一个ints 显式转换为 a double

c = a/(double)b;
于 2011-09-27T15:05:59.163 回答
14

这里是:

a) 除以两个ints 总是执行整数除法。因此,a/b在您的情况下,结果只能是int.

如果您想保留aandbints,但仍将它们完全分开,则必须将其中至少一个转换为 double: (double)a/bor a/(double)bor (double)a/(double)b

b)c是 a double,因此它可以接受int赋值时的值:自动int转换为double并赋值给c

c) 请记住,在赋值时,首先=计算右边的表达式(根据上面的规则(a),不考虑左边的变量)然后赋值给左边的变量(根据( b) 上述)。我相信这完成了画面。==

于 2011-09-27T15:15:35.157 回答
13

除了极少数例外(我只能想到一个),C++ 从表达式本身确定表达式(或子表达式)的全部含义。你对表达式的结果做什么并不重要。在您的情况下,在表达式中a / bdouble看不到;一切都是int。所以编译器使用整数除法。只有得到结果后,它才会考虑如何处理它,并将其转换为double.

于 2011-09-27T15:11:24.200 回答
8

当您将两个整数相除时,结果将是一个整数,而不管您将它存储在一个双精度数中。

于 2011-09-27T15:06:39.727 回答
7

c是一个double变量,但分配给它的值是一个int值,因为它是两个ints 相除的结果,这给了你“整数除法”(删除余数)。所以这条线上发生的事情c=a/b

  1. a/b被评估,创建一个临时类型int
  2. 临时的值c在转换为 type 后被赋值double

的值a/b是在不参考其上下文的情况下确定的(分配给double)。

于 2011-09-27T15:04:50.073 回答
6

在 C++ 语言中,子表达式的结果永远不会受到周围上下文的影响(有一些罕见的例外)。这是该语言仔细遵循的原则之一。该表达式c = a / b包含一个独立的子表达式a / b,该子表达式独立于该子表达式之外的任何内容进行解释。该语言并不关心您稍后会将结果分配给double. a / b是整数除法。别的什么都无所谓。您将在语言规范的许多方面看到这一原则。这就是 C++(和 C)的工作原理。

我上面提到的一个异常示例是函数重载情况下的函数指针分配/初始化

void foo(int);
void foo(double);

void (*p)(double) = &foo; // automatically selects `foo(fouble)`

这是赋值/初始化的左侧影响右侧行为的一种情况。(此外,对数组的引用初始化可防止数组类型衰减,这是类似行为的另一个示例。)在所有其他情况下,右侧完全忽略左侧。

于 2011-09-27T16:20:15.507 回答
5

/运算符可用于整数除法或浮点除法。你给它两个整数操作数,所以它进行整数除法,然后将结果存储在一个双精度数中。

于 2011-09-27T15:07:32.697 回答
3

这在技术上是依赖于语言的,但几乎所有语言都以相同的方式对待这个主题。当表达式中的两个数据类型之间存在类型不匹配时,大多数语言会尝试=根据一组预定义的规则将一侧的数据强制转换为匹配另一侧的数据。

当将两个相同类型的数(整数、双精度数等)相除时,结果将始终为相同类型(因此 'int/int' 将始终导致 int)。

在这种情况下,您可以 在计算后将double var = integer result 整数结果转换为双精度,在这种情况下,小数数据已经丢失。(大多数语言都会进行这种转换以防止类型不准确而不会引发异常或错误)。

如果您想将结果保持为双倍,您将想要创建一个您拥有的情况 double var = double result

最简单的方法是强制等式右侧的表达式转换为双精度:

c = a/(double)b

整数和双精度数之间的除法将导致整数转换为双精度数(请注意,在进行数学运算时,编译器通常会“向上转换”为最具体的数据类型,这是为了防止数据丢失)。

在向上转换之后,a最终会变成双打,现在你有两个双打之间的划分。这将创建所需的划分和分配。

再次,请注意这是特定于语言的(甚至可以是特定于编译器的),但是几乎所有语言(当然是我能想到的所有语言)都以相同的方式对待这个示例。

于 2011-09-27T15:12:16.457 回答
1

重要的是计算元素之一是 float-double 类型。然后要获得双重结果,您需要转换此元素,如下所示:

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

或 c = a / static_cast(b);

或者你可以直接创建它::

c = 7.0 / 3;

请注意,计算元素之一必须具有“.0”以指示浮点双精度类型除以整数。否则,尽管 c 变量是双精度的,但结果也将为零(整数)。

于 2020-03-06T11:47:35.083 回答
1

出于上述相同的原因,您必须将 'a' 或 'b' 之一转换为双精度类型。另一种方法是使用:

double c = (a+0.0)/b;

分子被(隐式)转换为双精度数,因为我们添加了双精度数,即0.0

于 2020-09-05T14:48:11.307 回答