为什么会出现在下面的片段中
int a = 7; int b = 3; double c = 0; c = a / b;
c最终的值是2,而不是人们所期望的2.3333。如果 a和 b是双精度的,那么答案就是2.333。但是可以肯定的是,因为 c已经是一个双精度的,它应该已经与整数工作?
c
a
b
那为什么 int/int=double不起作用呢?
int/int=double
c是一个 double变量,但是分配给它的值是一个 int值,因为它是由两个 int除法得到的,这样就得到了“整数除法”(去掉余数)。所以在 c=a/b行发生的是
double
int
c=a/b
a/b
a/b的值是在不参考其上下文(赋值给 double)的情况下确定的。
这是因为您使用的是 operator/的整数除法版本,它接受2个 int并返回一个 int。为了使用返回 double的 double版本,必须显式地将至少一个 int强制转换为 double。
operator/
c = a/(double)b;
当你划分两个整数时,结果将是一个整数,而不管你把它存储在一个双精度数中。
/运算符可用于整数除法或浮点除法。你给它两个整数操作数,所以它进行整数除法,然后结果被存储在一个 double 中。
/
除了极少数例外(我只能想到一个) ,C + + 确定了 表达式(或子表达式)的全部意义 你怎么处理这个表达式的结果并不重要。 在您的例子中,表达式 a / b中没有 double 所以编译器使用整数除法。 只有得到结果之后,它才会考虑如何处理它,而且 转换成 double。
a / b
从技术上讲,这是一个依赖于语言的问题,但是几乎所有的语言对待这个问题都是一样的。当表达式中的两个数据类型之间存在类型不匹配时,大多数语言都会尝试根据一组预定义的规则将数据强制转换到 =的一侧,以匹配另一侧的数据。
=
当把两个相同类型的数除以(整数、双精度数等)时,结果总是相同的类型(所以‘ int/int’总是会得到 int)。
在这种情况下,你有 double var = integer result 它将整数结果强制转换为双 在计算之后,在这种情况下,小数数据已经丢失。(大多数语言都会进行这种强制转换,以防止类型不准确而不引发异常或错误)。
double var = integer result
如果你想保持结果是双精度的,你就要创造一种情况 double var = double result
double var = double result
最简单的方法是强制方程右边的表达式翻倍:
c = a/(double)b
整数和双精度数之间的除法将导致整数转换为双精度数(请注意,在进行数学运算时,编译器通常会“转换”为最具体的数据类型,这是为了防止数据丢失)。
抛出后,a将作为一个双打结束,现在你有除法之间的两个双打。这将创建所需的划分和分配。
再次强调,请注意这是特定于语言的(甚至可以是特定于编译器的) ,然而几乎所有的语言(当然是我能想到的所有语言)对待这个例子都是一样的。
这就是:
A)除两个 int总是执行整数除法。所以在你的例子中,a/b的结果只能是 int。
如果你想保持 a和 b作为 int,然而完全分开他们,你必须铸造他们中的至少一个翻倍: (double)a/b或 a/(double)b或 (double)a/(double)b。
(double)a/b
a/(double)b
(double)a/(double)b
B) c是一个 double,所以它可以 接受一个 int值的分配: int是自动转换为 double和分配到 c。
C)记住,在赋值时,=右边的表达式是计算 第一(根据上面的(a)规则,不考虑 =左边的变量)和 那么(根据上面的(b))赋值给 =左边的变量。我相信这就是全部了。
在 C + + 语言中,子表达式的结果从不受周围上下文的影响(除了一些罕见的例外情况)。这是语言谨慎遵循的原则之一。表达式 c = a / b包含一个独立的子表达式 a / b,它的解释独立于该子表达式之外的任何内容。语言并不关心您稍后将结果分配给 double。a / b是一个整数除法。其他的都不重要。您将在语言规范的许多角落看到遵循这一原则。这就是 C + + (和 C)的工作原理。
c = a / b
我在上面提到的一个例外是在有函数指针函数重载的情况下的赋值/初始化
void foo(int); void foo(double); void (*p)(double) = &foo; // automatically selects `foo(fouble)`
在这种情况下,赋值/初始化的左侧会影响右侧的行为。(另外,引用到数组的初始化可以防止数组类型衰减,这是类似行为的另一个例子。)在所有其他情况下,右边完全忽略了左边。
重要的是计算的要素之一是浮点型。然后,为了得到一个双重结果,你需要对这个元素进行强制转换,如下所示:
c = static_cast<double>(a) / b;
或者 C = a/static _ cast (b) ;
或者你可以直接创建:
c = 7.0 / 3;
注意,计算元素之一必须有“ .0”才能表示 float-double 类型除以整数。否则,尽管 c 变量是双精度的,但结果也是零(一个整数)。
出于上述同样的原因,您必须将‘ a’或‘ b’之一转换为双重类型。另一种方法是使用:
double c = (a+0.0)/b;
分子被(隐式地)转换为双精度数,因为我们给它加了一个双精度数,即 0.0。