div()库函数的目的是什么?

时间:2012-07-30 16:43:59

标签: c division standard-library

当c有/运算符来划分两个数字时,拥有div() library function的目的是什么?

是否有任何情况/无法使用,div()可以?

6 个答案:

答案 0 :(得分:13)

来自C99理由文件:

  

(7.20.6.2 div,ldiv和lldiv函数)因为当涉及负操作数时,C89具有用于划分有符号整数的实现定义语义,所以发明了C99中的div和ldiv以及lldiv以提供明确指定的语义有符号整数除法和余数运算的语义。采用的语义与Fortran中的语义相同。由于这些函数同时返回商和余数,因此它们也可以作为有效建模底层硬件的便捷方式   计算两个结果作为同一操作的一部分。 [...]   现在C99需要类似语义的除法运算符,这是新的主要原因   使用div,ldiv或lldiv的程序是同时获得商和余数。

答案 1 :(得分:2)

div_t是一个结构,其中包含一个商一个余数成员。例如:

typedef struct {
    int quot;
    int rem;
} div_t;

div函数的一些简单实现使用/%运算符。您还可以看到this topic

答案 2 :(得分:2)

div()会返回分部的result remainder。因此,您无需使用%运算符即可找到remainder

答案 3 :(得分:2)

引自C Programming: A Modern Approach, 2nd Edition,第26章“问答”部分。

  

问:为什么div和ldiv函数存在?我们不能只使用/和%运算符吗?

     

A:divldiv/%不太相同。召回   第4.1节将/%应用于负操作数不会产生   便携式结果为C89。如果ij为负,则是否   {<1>定义了实现,将i / j向上或向下取整,这是<   i % j。另一方面,由divldiv计算得出的答案   不依赖于实施。商四舍五入为零。   余数根据公式n = q x d + r计算,   其中n是原始数字,q是商,d是除数,   r是余数。以下是一些示例:

 n      |  d     |  q     |  r
--------|--------|--------|--------
 7      |  3     |  2     |  1
-7      |  3     | -2     | -1
 7      | -3     | -2     |  1
-7      | -3     |  2     | -1
     

在C99中,{strong>保证/%运算符产生与以下结果相同的结果   divldiv

     

效率是divldiv存在的另一个原因。许多机器都有   可以同时计算商和余数的指令,因此调用div   或ldiv可能比分别使用/%运算符要更快

答案 4 :(得分:1)

正如其他人所说,div()会给你两个 商和其余的。这是因为(软件)整数 大多数C运行时使用的除法算法都是相同的 时间。

如果目标计算机没有硬件分隔符,则/ 运营商通常会转而调用div()和。{ 其余的被扔掉了。 %同样的事情发生了 运算符,除了它是被抛出的商。所以,如果你是 做这样的事情:

quot = a / b;
rem = a % b;
你正在调用除法程序两次(如果是,那么除法很慢) 您的计算机不在硬件中执行此操作。因此使用起来更快 div()获得两者。

(当然,它的可读性也差,你是否真的获得了任何 性能优势取决于您的特定平台和编译器。 如果你已经确定它,你应该只切换到div() 性能瓶颈。记住Knuth所说的过早的事情 优化。)

答案 5 :(得分:0)

速度太慢,但多余。 至少 glibc doc 声明了使用 gcc 的情况。 我尝试用 div 重新实现现有的 itoa() 函数(整数到 ascii),期望 gcc 为这种微不足道的事情提供内置实现,但 gcc 没有。

char *p = buf;
div_t d = {.quot = n};

while (1)
    d = div (d.quot, 10) ,
    *p++ = '0' + d.rem   ;

上面的代码比单独的操作符慢 5..7 倍:

char *p = buf;

while (1)
    *p++ = '0' + n % 10,
    n /= 10;