div函数有用吗(stdlib.h)
Is div function useful (stdlib.h)?
在C中有一个叫做div的函数,c++ (stdlib.h)
div_t div(int numer, int denom);
typedef struct _div_t
{
int quot;
int rem;
} div_t;
但是C、c++有/和%操作符
我的问题是:"当有/和%操作符时,div函数有用吗?"
是的,它在一次运算中计算商和余数。
除此之外,同样的行为可以通过/
+ %
来实现(并且一个体面的优化器无论如何都会将它们优化成单个div
)。
总结一下:如果您关心挤出最后一点性能,这可能是您的选择函数,特别是如果您的平台上的优化器不是那么先进。嵌入式平台通常就是这种情况。
div()函数返回一个结构,其中包含第一个参数(分子)除以第二个参数(分母)的商和余数。有四种变体:
-
div_t div(int, int)
-
ldiv_t ldiv(long, long)
-
lldiv_t lldiv(long long, long long)
-
imaxdiv_t imaxdiv(intmax_t, intmax_t
(intmax_t表示系统上可用的最大整数类型)
div_t
结构如下:
typedef struct
{
int quot; /* Quotient. */
int rem; /* Remainder. */
} div_t;
实现只使用/
和%
操作符,所以它不是一个非常复杂或必要的函数,但它是C标准的一部分(由[ISO 9899:201x][1]定义)。
参见GNU libc中的实现:
/* Return the `div_t' representation of NUMER over DENOM. */
div_t
div (numer, denom)
int numer, denom;
{
div_t result;
result.quot = numer / denom;
result.rem = numer % denom;
/* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
NUMER / DENOM is to be computed in infinite precision. In
other words, we should always truncate the quotient towards
zero, never -infinity. Machine division and remainer may
work either way when one or both of NUMER or DENOM is
negative. If only one is negative and QUOT has been
truncated towards -infinity, REM will have the same sign as
DENOM and the opposite sign of NUMER; if both are negative
and QUOT has been truncated towards -infinity, REM will be
positive (will have the opposite sign of NUMER). These are
considered `wrong'. If both are NUM and DENOM are positive,
RESULT will always be positive. This all boils down to: if
NUMER >= 0, but REM < 0, we got the wrong answer. In that
case, to get the right answer, add 1 to QUOT and subtract
DENOM from REM. */
if (numer >= 0 && result.rem < 0)
{
++result.quot;
result.rem -= denom;
}
return result;
}
div()的语义不同于%和/的语义,这在某些情况下很重要。这就是为什么下面的代码是在精神病的答案中显示的实现:
if (numer >= 0 && result.rem < 0)
{
++result.quot;
result.rem -= denom;
}
%可以返回一个负的答案,而div()总是返回一个非负的余数。
查看WikiPedia条目,特别是"div总是向0舍入,不像C语言中的普通整数除法,其中负数的舍入取决于实现。"
div()
满足了c99之前的需求:可移植性
在C99之前,具有负操作数的a / b
的商的舍入方向取决于实现。对于div()
,舍入方向不是可选的,但指定朝向0。div()
提供统一的便携式分区。次要的使用是当代码需要同时计算商和余数时潜在的效率。
有了C99及以后的版本,div()
和/
指定了相同的圆方向,并且有更好的编译器优化了附近的a/b
和a%b
代码,这种需求就减少了。
这是div()
和的令人信服的原因,它解释了udiv_t udiv(unsigned numer, unsigned denom)
在C规范中缺席的原因:a/b
使用负操作数的实现依赖结果的问题即使在c99之前的unsigned
中也不存在。
可能是因为在许多处理器上,div指令同时产生两个值,并且您总是可以指望编译器能够识别相同输入上相邻的/和%操作符可以合并为一个操作。
如果两个值都需要,则花费的时间更少。在进行除法运算时,CPU总是同时计算余商。如果使用"/"answers"%"一次,cpu将计算两个数字的两倍。
(原谅我英语不好,我不是母语)
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 为什么这个自定义分配器的析构函数在 GCC/MSVS 的 stdlib 中被调用两次
- 从 GetProcAddress 获取的函数指针在使用 stdlib 时会使程序崩溃
- 什么是 stdlib system() 函数的 Win32 API 等效项?
- 使用stdlib函数而不包含stdlib.h
- div函数有用吗(stdlib.h)
- 为什么c++ stdlib rand()函数在不同平台上对相同的种子给出不同的值?
- C++向量构造函数抛出std::out_of_range异常(Microsoft C++stdlib)