整数与浮动分部 - >谁负责提供结果?

时间:2010-08-15 16:05:23

标签: c++ c integer division integer-division

我已经在C ++中编程了一段时间,但突然有了疑问,并想与Stackoverflow社区进行澄清。

当一个整数除以另一个整数时,我们都知道结果是一个整数并且是明智的,浮点除以浮点也是一个浮点数。

但是谁负责提供这个结果?是编译器还是DIV指令?

6 个答案:

答案 0 :(得分:12)

这取决于您的架构是否 DIV指令。如果您的体系结构具有整数和浮点除法指令,则编译器将针对代码指定的情况发出正确的指令。语言标准规定了类型提升的规则,以及是否应在每种可能的情况下使用整数或浮点除法。

如果只有整数除法指令或只有浮点除法指令,编译器将内联一些代码或生成对数学支持库的调用来处理除法。除法指令的速度非常慢,因此大多数编译器会尽可能地优化它们(例如,用移位指令替换,或者预先计算结果以进行编译时常量的除法)。

答案 1 :(得分:3)

编译器将根据所使用的变量类型在编译时决定需要什么形式的除法 - 在一天结束时,将涉及一种或另一种形式的DIV(或FDIV)指令。

答案 2 :(得分:3)

硬件除法指令几乎从不包括整数和浮点之间的转换。如果你得到除法指令(它们有时被省略,因为除法电路很大而且很复杂),它们实际上肯定是“用int分割int,生成int”和“浮动除浮动,产生浮动” 。通常情况下,输入和输出都是相同的大小。

编译器负责在这些原语之上构建源代码中编写的任何操作。例如,在C中,如果用浮点数除以一个int,编译器将发出一个int-to-float转换,然后是一个float divide。

(确实存在古怪的异常。我不知道,但是我不会把它放在VAX之上,因为它有“按浮点数”类型指令。安腾并没有真正的除法指令,但是“divide helper”对于浮点只有 ,你必须在浮动除法之上伪造整数除法!)

答案 3 :(得分:1)

C ++标准中最重要的规则之一是“似乎”规则:

  

本国际标准中的语义描述定义了参数化的非确定性抽象机器。本国际标准对符合实施的结构没有要求。特别是,它们不需要复制或模拟抽象机器的结构。相反,需要符合实现来模拟(仅)抽象机器的可观察行为,如下所述。

与您的问题相关的意思是,只要它完成,分割的哪个组件就无关紧要。它可以由DIV机器代码执行,如果没有针对相关处理器的适当指令,则可以由更复杂的代码执行。

它还可以:

  1. 如果合适,可以使用位移操作替换操作,并且可能更快。
  2. 如果在编译时可计算,或者如果例如可以计算,则用文字替换该操作。处理x / y时,可以在编译时显示y始终为1.
  3. 如果在编译时可以显示整数除以零,则将该操作替换为异常抛出。

答案 4 :(得分:1)

你的问题没有意义。 DIV指令本身不执行任何。无论你多么大声喊叫,即使你试图贿赂它,也不会对任何东西负责

当您使用编程语言[X]进行编程时,[X]编译器的唯一责任是制作一个执行您在源代码中描述的程序的程序

如果请求除法,编译器将决定如何进行除法。如果您要定位的CPU有一个操作码,则可能会生成DIV指令的操作码。它可能是通过在编译时预先计算除法,并将结果直接插入到程序中(假设两个操作数在编译时都是已知的),或者可以通过生成一起指令序列来完成模拟一个分裂。

但是总是直到编译器。除非根据C ++标准解释,否则您的C ++程序没有任何效果。如果将其解释为纯文本文件,则不会执行任何。如果您的编译器将其解释为Java程序,它将阻塞并拒绝它。

DIV指令对C ++标准一无所知。另一方面,C ++编译器是编写的,其唯一目的是理解C ++标准,并根据它转换代码。

编译器始终负责。

答案 5 :(得分:0)

实际上

C99标准定义“当整数被分割时,/运算符的结果 是任何小数部分的代数商 “并且在脚注中添加了”这通常被称为'截断为零'。“

历史

从历史上看,语言规范是负责任的。

Pascal defines its operators以便使用/进行除法总是返回real(即使你用它来划分2个整数),如果你想要除以整数并得到一个整数结果,您使用div运算符。 (Visual Basic具有类似的区别,并使用\运算符进行整数除法,返回整数结果。)

在C中,如果您想要一个浮点结果,则决定通过将一个整数操作数强制转换为float来进行相同的区分。按照您在许多C派生语言中描述的方式处理整数与浮点类型已成为惯例。我怀疑这个约定可能起源于Fortran。