【问题标题】:Evaluation and Truncation评估和截断
【发布时间】:2018-10-04 07:17:55
【问题描述】:

首先发生什么,截断或求值?如果我这样做:

int a = (2+3)*10.5;

a 得到 52,但如果我这样做:

int a = 30 / 4 * 5; 

a 得到 35。

所以一个表达式首先被求值然后被截断。那么截断的值用于其他计算呢?因为在第二个语句中,“30/4”首先被评估,然后被截断为 7。这个的确切规则是什么?文档中的任何内容...我不是在谈论类型转换,在这种情况下只是截断,比如表达式被一个接一个地截断?

【问题讨论】:

  • 使用运算符优先级来扣除数据的类型......如果/*具有相同的优先级和左关联性,它们将作为(30 / 4) * 5执行,不会他们? 30 / 4 => 77 * 5 => 35。正确的?没有截断,您将两个整数相除,并得到int 结果。试试30.0 / 4 * 5 看看会发生什么。

标签: c truncation


【解决方案1】:

您有点问错了问题,没有单独的评估和截断步骤之类的东西。截断是类型转换的副作用,如果转换后的值不能在目标类型中精确表示,比如

double d = 2.5;
int i = d;       // 2.5 is truncated as a side effect of converting to int

因此,您必须知道在计算表达式时如何转换操作数。确切的规则有点复杂,我将在这里重点介绍基础知识。通常,对于算术运算符,如果操作数没有相同的类型,则其中一个会以某种方式转换,以便可以表示两个值。在您的第一个示例中:

int a = (2+3)*10.5;

23 都是 int 类型,所以它们只是被添加了——结果 (5) 又是 int 类型。

但是10.5 的类型为double。所以,5 也被转换为double,结果是52.5。只是因为您将其分配给 int,它会被转换回 int,因此必须进行截断。

在你的第二个例子中:

int a = 30 / 4 * 5;

304 都具有 int 类型。因此,不发生转换,直接进行除法。

这里有一个问题:将两个整数相除是一个整数除法,它再次导致int(这里:7)。这不是截断,而是整数除法的定义方式。事实上,您可能在学校早期就使用了一种名为long division with remainder 的算法了解了该操作。 C 中有一个“相反的”运算模 (%),它可以为您提供该除法的 余数

所以,这里有int 类型的结果7,然后乘以5,另一个int,因此,同样,没有转换——最终结果是35

检查如果你写会发生什么

int a = 30.0 / 4 * 5;

相反。现在,/ 的第一个操作数是双精度数,所以4 也被转换为double,结果是7.5——这又是一个double,导致5 被转换到double 并产生37.5 的最终结果。

这再次转换为int,因为您将其分配给int,并且截断产生37


请注意运算符 / 在这里表示两种不同的东西(实数除法与整数除法),具体取决于其操作数的类型。

【讨论】:

    【解决方案2】:

    不要从截断求值的角度来思考。相反,请考虑分组整数除法。为了进行充分的分析,还需要引入一些其他术语:我已经注意斜体这些。

    表达式 (2 + 3) * 10.5 由于括号而被明确分组。所以5 * 10.5是一个中间步骤;这是一个double 类型,因为5int 转换为double。此表达式的值为52.5,当分配给int 时,它会被截断为52

    30 / 4 * 5 从左到右分组(乘法和除法具有相同的优先级,因此运算符的关联性发挥作用),所以它等价于(30 / 4) * 530 / 47(整数除法),然后乘以 5 得到结果。

    一个更有趣的例子是30 / 4 * 5.0。那是 still 35 但是是 double 类型。分组仍为(30 / 4) * 5.0

    【讨论】:

      【解决方案3】:

      会发生什么取决于所涉及的值的类型。

      233045 都是 int 类型。

      10.5 的类型为 double

      因此(2+3)*10.5 执行23 的整数加法,得到5(另一个int),然后是5.0(从5 隐式转换而来)和@987654336 的浮点乘法@,产生52.5。这个数字被分配给int,它隐式地将它截断为52

      另一方面,在30 / 4 * 5 中,所有操作数都是ints,没有任何内容转换为double。因此30 / 4 执行整数除法,得到7,然后乘以5,得到35

      没有单独的评估和截断。截断可以作为类型转换的一部分发生,但在30 / 4 中,您不是在查看单独的截断和评估步骤,而是单个操作(整数除法)。当然,由于这个结果的类型是int,所以它不能有任何小数位。

      【讨论】:

        猜你喜欢
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        • 2012-02-04
        • 1970-01-01
        • 2012-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多