以下 C++ 代码用于 ->“#define idiv(a, b) (((a) + (b) / 2) / (b))”?

Ala*_*kov 4 c++ optimization

我正在处理经常使用一些重要优化的代码。是什么

#define idiv(a, b) (((a) + (b) / 2) / (b))
Run Code Online (Sandbox Code Playgroud)

用于?为什么不简单

#define idiv(a, b) ((a)/(b) + 0.5)
Run Code Online (Sandbox Code Playgroud)

是整数除法溢出保护还是其他什么?

Dev*_*lar 5

整数除法向零截断。假设(从宏的名称,i div)您的参数是整数类型,((a)/(b) + 0.5)您到达之前被截断+ 0.5,因此无论如何您总是会向下舍入。

(((a) + (b) / 2) / (b))结果大于X.5,不使用浮点运算。

注意:您标记了您的问题 C++。在 C++ 中,你不应该“宏”任何东西,真的。检查 Marek 对模板解决方案的回答(但也要注意它实际上不适用于负值)。


vll*_*vll 5

您建议的修改并不等效,因为a/b参数为整数时是整数除法。您应该首先将参数转换为浮点数。

第一个宏避免转换为浮点,这可能会更快。此外,将值转换为浮点数再转换回整数可能会失去精度,因为并非所有整数都可以精确地表示为浮点数。


Mar*_*k R 5

这段代码是C宏,在 C++ 中被认为是一种非常糟糕的做法。在 C++ 中,您应该使用模板(有人说这是更智能的宏)。

template<typename T>
constexpr T idiv(T a, T b) {
    return (a + b / 2) / b;
}
Run Code Online (Sandbox Code Playgroud)

这段代码仍然没有达到作者的预期。计划是将结果四舍五入到最接近的整数值,但如果一个参数为负值,则失败。

看到这个并注意失败a: 4 b: -2

还有整数溢出问题(见最后一个测试用例)。