为什么分配两个int在分配给double时不会产生正确的值?

时间:2011-09-27 15:02:56

标签: c++ variables double integer-division

如何在以下代码段中

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

c最终得到的值是2,而不是2.3333,正如人们所期望的那样。如果ab是双打,则答案确实转为2.333。但肯定是因为c已经是双重的,它应该与整数一起工作吗?

那么int/int=double怎么办不起作用?

10 个答案:

答案 0 :(得分:138)

这是因为您使用operator/的整数除法版本,需要2 int s并返回int。要使用返回double的{​​{1}}版本,必须至少将其中一个double显式转换为int

double

答案 1 :(得分:11)

这是:

a)划分两个int s始终执行整数除法。因此,a/b的结果只能是int

如果您希望将ab保留为int,然后将它们完全分开,则必须至少将其中一个转换为加倍:(double)a/b或{ {1}}或a/(double)b

b)(double)a/(double)bc,因此它可以接受关于分配的double值:int会自动转换为{ {1}}已分配给int

c)请记住,在分配时,double右边的表达式首先计算 (根据上面的规则(a),并且不考虑左边的变量) c)和然后分配给=左侧的变量(根据上面的(b))。我相信这样就完成了。

答案 2 :(得分:9)

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

答案 3 :(得分:6)

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

答案 4 :(得分:5)

c是一个double变量,但分配给它的值是int值,因为它是由两个int的分割产生的,它为您提供“整数除法”(删除余数)。那么行c=a/b中发生的是

    评估
  1. a/b,创建int
  2. 类型的临时值
  3. 转换为c后,将临时值分配给double
  4. 确定a/b的值时不参考其上下文(赋值给double)。

答案 5 :(得分:4)

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

答案 6 :(得分:4)

在C ++语言中,subexpresison的结果不会受到周围环境的影响(有一些罕见的例外)。这是该语言所遵循的原则之一。表达式c = a / b包含独立的子表达式a / b,它独立于子表达式之外的任何内容进行解释。该语言并不关心您以后将结果分配给doublea / b是整数除法。其他任何事都无关紧要。您会在语言规范的许多角落看到这个原则。这就是C ++(和C)的工作方式。

我上面提到的异常的一个例子是在函数重载

的情况下的函数指针赋值/初始化
void foo(int);
void foo(double);

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

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

答案 7 :(得分:2)

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

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

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

如果您希望将结果保持为双倍,那么您将希望创建一个您拥有的情境 double var = double result

最简单的方法是强制等式右边的表达式转换为double:

c = a/(double)b

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

在向上移动之后,a将会变为双倍,现在你在两个双打之间进行划分。这将创建所需的分工和分配。

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

答案 8 :(得分:1)

重要的是计算的元素之一是浮点双精度型。然后,要获得双重结果,您需要像下面这样显示该元素:

setTagInput("");
return false; //<-------here it will work only if enter is pressed

或 c = a / static_cast(b);

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

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

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

答案 9 :(得分:1)

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

double c = (a+0.0)/b;

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