为什么分配给 double 时,两个 int 相除不能得到正确的值?

发布于 2025-01-11 16:44:01 字数 290 浏览 4 评论 0原文

为什么在下面的代码片段中,

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

c 最终的值为 2,而不是人们所期望的 2.3333。如果 ab 是双精度数,则答案确实为 2.333。但肯定是因为 c 已经是双精度数了,所以它应该可以处理整数吗?

那么为什么 int/int=double 不起作用呢?

How come that in the following snippet

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

c ends up having the value 2, rather than 2.3333, as one would expect. If a and b are doubles, the answer does turn to 2.333. But surely because c already is a double it should have worked with integers?

So how come int/int=double doesn't work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

寄居者 2025-01-18 16:44:01

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

c = a/(double)b;

This is because you are using the integer division version of operator/, which takes 2 ints and returns an int. In order to use the double version, which returns a double, at least one of the ints must be explicitly casted to a double.

c = a/(double)b;
爱要勇敢去追 2025-01-18 16:44:01

除了极少数例外(我只能想到一个),C++ 决定了
表达式(或子表达式)的完整含义
本身。您如何处理表达式的结果并不重要。
就您而言,在表达式 a / b 中,没有 double
视力;一切都是int。所以编译器使用整数除法。
只有当它得到结果后,它才会考虑如何处理它,并且
将其转换为double

With very few exceptions (I can only think of one), C++ determines the
entire meaning of an expression (or sub-expression) from the expression
itself. What you do with the results of the expression doesn't matter.
In your case, in the expression a / b, there's not a double in
sight; everything is int. So the compiler uses integer division.
Only once it has the result does it consider what to do with it, and
convert it to double.

小糖芽 2025-01-18 16:44:01

如下:

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

如果您想将 ab 保留为 int,但将它们完全分开,则必须将其中至少一个强制转换为 double:<代码>(double)a/b或a/(double)b​​(double)a/(double)b​​

b) c 是一个 double,因此它可以在赋值时接受一个 int 值:int 自动转换为 double 并分配给 c

c) 请记住,在赋值时,首先计算 = 右侧的表达式(根据上面的规则 (a),并且不考虑=) 并then 分配给 = 左侧的变量(根据上面的 (b))。我相信这就是完整的图景。

Here it is:

a) Dividing two ints performs integer division always. So the result of a/b in your case can only be an int.

If you want to keep a and b as ints, yet divide them fully, you must cast at least one of them to double: (double)a/b or a/(double)b or (double)a/(double)b.

b) c is a double, so it can accept an int value on assignement: the int is automatically converted to double and assigned to c.

c) Remember that on assignement, the expression to the right of = is computed first (according to rule (a) above, and without regard of the variable to the left of =) and then assigned to the variable to the left of = (according to (b) above). I believe this completes the picture.

单身狗的梦 2025-01-18 16:44:01

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

我上面提到的异常的一个例子是函数重载情况下的函数指针赋值/初始化。

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

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

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

In C++, the result of the sub-expression is never affected by the surrounding context (with some rare exceptions). This is one of the principles that the language carefully follows. The expression c = a / b consists of an independent sub-expression a / b, which is interpreted independently from anything outside that sub-expression. The language does not care that you later will assign the result to a double. a / b is an integer division. Anything else does not matter. You will see this principle followed in many corners of the language specification. That's just how C++ (and C) works.

One example of an exception I mentioned above is the function pointer assignment/initialization in situations with function overloading

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

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

This is one context where the left-hand side of an assignment/initialization affects the behavior of the right-hand side. (Also, reference-to-array initialization prevents array type decay, which is another example of similar behavior.) In all other cases the right-hand side completely ignores the left-hand side.

风筝在阴天搁浅。 2025-01-18 16:44:01

当您将两个整数相除时,结果将是一个整数,无论​​您是否将其存储在双精度型中。

When you divide two integers, the result will be an integer, irrespective of the fact that you store it in a double.

挖个坑埋了你 2025-01-18 16:44:01

c 是一个 double 变量,但分配给它的值是一个 int 值,因为它是两个 int 除法的结果s,它给你“整数除法”(去掉余数)。因此,c=a/b 行中发生的情况是

  1. a/b 进行求值,创建一个 int 类型的临时值(
  2. 该临时值的值)转换为 double 类型后分配给 c

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

c is a double variable, but the value being assigned to it is an int value because it results from the division of two ints, which gives you "integer division" (dropping the remainder). So what happens in the line c=a/b is

  1. a/b is evaluated, creating a temporary of type int
  2. the value of the temporary is assigned to c after conversion to type double.

The value of a/b is determined without reference to its context (assignment to double).

多情癖 2025-01-18 16:44:01

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

The / operator can be used for integer division or floating point division. You're giving it two integer operands, so it's doing integer division and then the result is being stored in a double.

病毒体 2025-01-18 16:44:01

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

当两个相同类型的数字(整数、双精度数等)相除时,结果将始终是相同的类型(因此“int/int”将始终生成 int)。

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

如果您想将结果保持为双倍,您将需要创造一种情况:
double var = double result

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

c = a/(double)b​​

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

向上转换后,a 将最终成为双精度数,现在您可以在两个双精度数之间进行除法。这将创建所需的划分和分配。

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

This is technically a language-dependent, but almost all languages treat this subject the same. When there is a type mismatch between two data types in an expression, most languages will try to cast the data on one side of the = to match the data on the other side according to a set of predefined rules.

When dividing two numbers of the same type (integers, doubles, etc.) the result will always be of the same type (so 'int/int' will always result in int).

In this case you have
double var = integer result
which casts the integer result to a double after the calculation in which case the fractional data is already lost. (most languages will do this casting to prevent type inaccuracies without raising an exception or error).

If you'd like to keep the result as a double you're going to want to create a situation where you have
double var = double result

The easiest way to do that is to force the expression on the right side of an equation to cast to double:

c = a/(double)b

Division between an integer and a double will result in casting the integer to the double (note that when doing maths, the compiler will often "upcast" to the most specific data type this is to prevent data loss).

After the upcast, a will wind up as a double and now you have division between two doubles. This will create the desired division and assignment.

AGAIN, please note that this is language specific (and can even be compiler specific), however almost all languages (certainly all the ones I can think of off the top of my head) treat this example identically.

雨后彩虹 2025-01-18 16:44:01

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

double c = (a+0.0)/b;

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

For the same reasons above, you'll have to convert one of 'a' or 'b' to a double type. Another way of doing it is to use:

double c = (a+0.0)/b;

The numerator is (implicitly) converted to a double because we have added a double to it, namely 0.0.

心是晴朗的。 2025-01-18 16:44:01

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

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


c = a / static_cast(b);

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

c = 7.0 / 3;

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

The important thing is one of the elements of calculation be a float-double type. Then to get a double result you need to cast this element like shown below:

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

or
c = a / static_cast(b);

Or you can create it directly::

c = 7.0 / 3;

Note that one of elements of calculation must have the '.0' to indicate a division of a float-double type by an integer. Otherwise, despite the c variable be a double, the result will be zero too (an integer).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文